Commit e4ba97de authored by Mario Bozhikov's avatar Mario Bozhikov
Browse files

Web Conntrollers for http requests and tests

No related merge requests found
Showing with 608 additions and 330 deletions
+608 -330
......@@ -3,6 +3,8 @@
*/
plugins {
// id("org.springframework.boot") version "3.1.2"
// id("io.spring.dependency-management")
id("student.management.java-common-conventions")
}
......
......@@ -2,10 +2,17 @@ package student.management.api;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@SpringBootApplication
@ComponentScan("student.management")
@EnableJpaRepositories("student.management.repository")
@EntityScan("student.management.data")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
package student.management.api.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import student.management.core.CourseService;
import student.management.core.models.AvgGradeDTO;
import student.management.core.models.course.CourseCreationReq;
import student.management.core.models.course.CourseDTO;
import student.management.core.models.course.CourseStudentGradeReq;
import student.management.core.models.course.CourseStudentGradeRes;
import student.management.core.models.course.CourseWithAvgGradeResponse;
import java.util.List;
@RestController
@RequestMapping("/api/courses")
public class CourseController {
private final CourseService courseService;
@Autowired
public CourseController(CourseService courseService) {
this.courseService = courseService;
}
@GetMapping
public ResponseEntity<List<CourseDTO>> getCourses(){
return new ResponseEntity<>(courseService.getAllCourses(), HttpStatus.FOUND);
}
@GetMapping("/asc-order")
public List<AvgGradeDTO> getCoursesOrdered(){
return courseService.getAverageGradeForStudentsPerCourse();
}
@GetMapping("/{id}")
public ResponseEntity<CourseDTO> getCourse(@PathVariable("id") Long courseID){
return new ResponseEntity<>(courseService.get(courseID), HttpStatus.FOUND);
}
@GetMapping(value = "/{id}/avg-grade")
public ResponseEntity<CourseWithAvgGradeResponse> getCourseAvgGrade(@PathVariable("id") Long courseID){
return new ResponseEntity<>(courseService.getAverageGrade(courseID), HttpStatus.OK);
}
@PostMapping
public ResponseEntity<CourseDTO> upsertCourse(@RequestBody CourseCreationReq courseCreationReq){
return new ResponseEntity<>(courseService.add(courseCreationReq), HttpStatus.CREATED);
}
@PatchMapping(value = "/{id}/teacher", params = "teacher_id")
public ResponseEntity<CourseDTO> upsertCourseTeacher(@PathVariable("id") Long courseID, @RequestParam("teacher_id") Long teacherID){
return new ResponseEntity<>(courseService.assignTeacher(courseID, teacherID), HttpStatus.OK);
}
@PatchMapping(value = "/{id}/student", params = "student_id")
public ResponseEntity<CourseDTO> upsertCourseStudent(@PathVariable("id") Long courseID, @RequestParam("student_id") Long studentID){
return new ResponseEntity<>(courseService.enrollStudent(courseID, studentID), HttpStatus.OK);
}
@PatchMapping("/{id}/student/grade")
public ResponseEntity<CourseStudentGradeRes> addGradeToStudent(@PathVariable("id") Long courseID, @RequestBody CourseStudentGradeReq courseStudentGradeReq){
return new ResponseEntity<>(courseService.updateStudentGrades(courseID, courseStudentGradeReq.studentId(), courseStudentGradeReq.grade()), HttpStatus.OK);
}
}
\ No newline at end of file
package student.management.api.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import student.management.core.StudentService;
import student.management.core.models.StructMapper;
import student.management.core.models.StudentDTO;
import java.util.List;
@RestController
@RequestMapping("/api/students")
public class StudentController {
private final StudentService studentService;
@Autowired
public StudentController(StudentService studentService) {
this.studentService = studentService;
}
@GetMapping
public ResponseEntity<List<StudentDTO>> getStudents() {
return new ResponseEntity<>(studentService.getAll(), HttpStatus.FOUND);
}
@GetMapping("/{id}")
public ResponseEntity<StudentDTO> getStudent(@PathVariable("id") Long studentID){
return new ResponseEntity<>(studentService.get(studentID), HttpStatus.FOUND);
}
@PostMapping
public ResponseEntity<StudentDTO> upsertStudent(@RequestBody StudentDTO studentDTO){
return new ResponseEntity<>(studentService.add(studentDTO), HttpStatus.CREATED);
}
}
package student.management.api.controllers;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import student.management.core.TeacherService;
import student.management.core.models.TeacherDTO;
import java.util.List;
@RestController
@RequestMapping("/api/teachers")
public class TeacherController {
private final TeacherService teacherService;
public TeacherController(TeacherService teacherService) {
this.teacherService = teacherService;
}
@GetMapping
public ResponseEntity<List<TeacherDTO>> getTeachers(){
return new ResponseEntity<>(teacherService.getAll(), HttpStatus.FOUND);
}
@GetMapping("/{id}")
public ResponseEntity<TeacherDTO> getTeacher(@PathVariable("id") Long teacherID) {
return new ResponseEntity<>(teacherService.get(teacherID), HttpStatus.FOUND);
}
@PostMapping
public ResponseEntity<TeacherDTO> upsertTeacher(@RequestBody TeacherDTO teacherDTO){
return new ResponseEntity<>(teacherService.add(teacherDTO), HttpStatus.CREATED);
}
}
package student.management.api.exceptions;
public class ErrorViewModel {
public void add(String message) {
}
}
package student.management.api.exceptions;
import org.hibernate.ObjectNotFoundException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandlerController extends ResponseEntityExceptionHandler {
@ExceptionHandler({ObjectAlreadyExistsException.class})
public ResponseEntity<Object> handleObjectAlreadyExistsException(ObjectAlreadyExistsException e, WebRequest request) {
ErrorViewModel errorViewModel = new ErrorViewModel();
errorViewModel.add(e.getMessage());
return this.handleExceptionInternal(e, errorViewModel, new HttpHeaders(), HttpStatus.CONFLICT, request);
}
@ExceptionHandler({IllegalArgumentException.class})
public ResponseEntity<Object> handleIllegalArgumentException(IllegalArgumentException e, WebRequest request) {
ErrorViewModel errorViewModel = new ErrorViewModel();
errorViewModel.add(e.getMessage());
return this.handleExceptionInternal(e, errorViewModel, new HttpHeaders(), HttpStatus.UNPROCESSABLE_ENTITY, request);
}
@ExceptionHandler({NullPointerException.class})
public ResponseEntity<Object> handleNullPointerException(NullPointerException e, WebRequest request) {
ErrorViewModel errorViewModel = new ErrorViewModel();
errorViewModel.add(e.getMessage());
return this.handleExceptionInternal(e, errorViewModel, new HttpHeaders(), HttpStatus.UNPROCESSABLE_ENTITY, request);
}
@ExceptionHandler({ObjectNotFoundException.class})
public ResponseEntity<Object> handleObjectNotFoundException(ObjectNotFoundException e, WebRequest request) {
ErrorViewModel errorViewModel = new ErrorViewModel();
errorViewModel.add(e.getMessage());
return this.handleExceptionInternal(e, errorViewModel, new HttpHeaders(), HttpStatus.NOT_FOUND, request);
}
// @ExceptionHandler({BadCredentialsException.class})
// public ResponseEntity<Object> handleAuthenticationException(BadCredentialsException e, WebRequest request) {
// ErrorViewModel errorViewModel = new ErrorViewModel();
// errorViewModel.add(e.getMessage());
// return this.handleExceptionInternal(e, errorViewModel, new HttpHeaders(), HttpStatus.UNAUTHORIZED, request);
// }
}
package student.management.api.exceptions;
public class ObjectAlreadyExistsException extends Exception {
}
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package student.management.cli;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import student.management.cli.controllers.CourseController;
import student.management.cli.controllers.StudentController;
import student.management.cli.controllers.TeacherController;
@SpringBootApplication()
@ComponentScan("student.management")
@EnableJpaRepositories("student.management.repository")
@EntityScan("student.management.data")
public class Cli {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Cli.class, args);
CourseController courseController = context.getBean(CourseController.class);
StudentController studentController = context.getBean(StudentController.class);
TeacherController teacherController = context.getBean(TeacherController.class);
DisplayMenu displayMenu = new DisplayMenu(courseController, studentController, teacherController);
displayMenu.start();
context.close();
}
}
package student.management.cli;
import org.springframework.stereotype.Component;;
import student.management.cli.controllers.CourseController;
import student.management.cli.controllers.StudentController;
import student.management.cli.controllers.TeacherController;
import student.management.cli.models.StudentCreationRequest;
import student.management.cli.models.TeacherCreationRequest;
import student.management.cli.models.course.CourseCreationRequest;
import student.management.cli.models.course.CourseGradeRequest;
import student.management.cli.models.course.CourseInsertionRequest;
import student.management.data.Degree;
import java.util.Scanner;
@Component
public class DisplayMenu {
private static final Scanner scanner = new Scanner(System.in);
private final CourseController courseController;
private final StudentController studentController;
private final TeacherController teacherController;
public DisplayMenu(CourseController courseController, StudentController studentController, TeacherController teacherController) {
this.courseController = courseController;
this.studentController = studentController;
this.teacherController = teacherController;
}
public void start(){
while (true) {
System.out.println("----- Student Management System -----");
System.out.println("1. Add a new course");
System.out.println("2. Add a new student");
System.out.println("3. Add a new teacher");
System.out.println("4. Add/remove a teacher to a specific course");
System.out.println("5. Add a student to a specific course");
System.out.println("6. Add a grade for a student in a specific course");
System.out.println("7. Show all students grouped by course");
System.out.println("8. Show all courses and their teachers and students");
System.out.println("9. Show the average grade for all students in a specific course");
System.out.println("10. Show a total average grade for a student");
System.out.println("0. Exit");
System.out.println("------------------------------------");
System.out.print("Enter your choice: ");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1 -> addNewCourse();
case 2 -> addNewStudent();
case 3 -> addNewTeacher();
case 4 -> assignTeacherToCourse();
case 5 -> addStudentToCourse();
case 6 -> addGradeToStudentInCourse();
case 7 -> showStudentsGroupedByCourse();
case 8 -> showAllCoursesWithTeachersAndStudents();
case 9 -> showAverageGradeForCourse();
case 10 -> showTotalAverageGradeForStudent();
case 0 -> {
System.out.println("Exiting the program. Goodbye!");
System.exit(0);
}
default -> System.out.println("Invalid choice. Please try again.");
}
}
}
private void addNewStudent(){
System.out.print("Enter student name: ");
String name = scanner.nextLine();
System.out.print("Enter student age: ");
int age = Integer.parseInt(scanner.nextLine());
StudentCreationRequest request = new StudentCreationRequest(name, age);
studentController.add(request);
}
private void addNewTeacher() {
System.out.print("Enter teacher name: ");
String name = scanner.nextLine();
System.out.println("Available degrees: MSc, BSc, PHD");
System.out.print("Enter the teacher's degree: ");
String degreeStr = scanner.nextLine();
Degree degree;
try {
degree = Degree.valueOf(degreeStr);
} catch (IllegalArgumentException e) {
System.out.println("Invalid degree choice. Setting degree to default (BSc).");
degree = Degree.BSc;
}
TeacherCreationRequest request = new TeacherCreationRequest(name, degree);
teacherController.add(request);
}
private void addNewCourse(){
System.out.print("Enter course name: ");
String name = scanner.nextLine();
System.out.print("Enter course total hours: ");
int totalHours = Integer.parseInt(scanner.nextLine());
CourseCreationRequest request = new CourseCreationRequest(name, totalHours);
courseController.post(request);
}
private void assignTeacherToCourse(){
System.out.print("Enter course ID: ");
long courseId = Long.parseLong(scanner.nextLine());
System.out.print("Enter teacher ID: ");
long teacherId = Long.parseLong(scanner.nextLine());
CourseInsertionRequest request = new CourseInsertionRequest(courseId, teacherId);
courseController.postTeacher(request);
}
private void addStudentToCourse(){
System.out.print("Enter course ID: ");
long courseId = Long.parseLong(scanner.nextLine());
System.out.print("Enter student ID: ");
long studentId = Long.parseLong(scanner.nextLine());
CourseInsertionRequest request = new CourseInsertionRequest(courseId, studentId);
courseController.postStudent(request);
}
private void addGradeToStudentInCourse() {
System.out.print("Enter course ID: ");
long courseId = Long.parseLong(scanner.nextLine());
System.out.print("Enter student ID: ");
long studentId = Long.parseLong(scanner.nextLine());
System.out.print("Enter grade (A, B, C, D, E): ");
String gradeInput = scanner.nextLine().toUpperCase();
CourseGradeRequest request = new CourseGradeRequest(courseId, studentId ,gradeInput);
courseController.postGrade(request);
}
private void showStudentsGroupedByCourse(){
courseController.getStudentsAverageGradePerCourse();
}
private void showAllCoursesWithTeachersAndStudents(){
courseController.getAll();
}
private void showAverageGradeForCourse(){
System.out.print("Enter course ID: ");
long courseId = Long.parseLong(scanner.nextLine());
courseController.getAverageGrade(courseId);
}
private void showTotalAverageGradeForStudent(){
System.out.print("Enter student ID: ");
long studentId = Long.parseLong(scanner.nextLine());
studentController.getStudentAverageGrade(studentId);
}
}
package student.management.cli.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import student.management.cli.models.course.CourseCreationRequest;
import student.management.cli.models.course.CourseGradeRequest;
import student.management.cli.models.course.CourseInsertionRequest;
import student.management.core.CourseService;
import student.management.core.models.AvgGradeDTO;
import student.management.data.Course;
import student.management.data.GradeEnum;
import java.util.List;
@Controller
public class CourseController {
private final CourseService courseService;
@Autowired
public CourseController(CourseService courseService) {
this.courseService = courseService;
}
public void post(CourseCreationRequest request){
System.out.println(courseService.add(new Course(request.name(), request.totalHours())).toString());
}
public void postTeacher(CourseInsertionRequest request){
System.out.println(courseService.assignTeacher(request.courseID(), request.entityID()).toString());
}
public void postStudent(CourseInsertionRequest request){
System.out.println(courseService.enrollStudent(request.courseID(), request.entityID()).toString());
}
public void getAll(){
System.out.println(courseService.getAllCourses());
}
public void getStudentsAverageGradePerCourse(){
List<AvgGradeDTO> averageGradesList = courseService.getAverageGradeForStudentsPerCourse();
for (AvgGradeDTO dto : averageGradesList) {
System.out.println(dto.toString());
}
}
public void postGrade(CourseGradeRequest request){
System.out.println(courseService.updateStudentGrades(request.courseID(), request.studentID(), GradeEnum.valueOf(request.gradeEnum())));
}
public void getAverageGrade(long courseID){
System.out.println(courseService.getAverageGrade(courseID));
}
}
package student.management.cli.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import student.management.core.GradeService;
import student.management.core.StudentService;
import student.management.cli.models.StudentCreationRequest;
import student.management.data.Student;
@Controller
public class StudentController {
private final StudentService studentService;
private final GradeService gradeService;
@Autowired
public StudentController(StudentService studentService, GradeService gradeService) {
this.studentService = studentService;
this.gradeService = gradeService;
}
public void add(StudentCreationRequest request) {
System.out.println(studentService.add(new Student(request.name(), request.age())).toString());
}
public void getStudentAverageGrade(long studentID){
System.out.println(gradeService.getAverageGradeForStudent(studentID));
}
}
package student.management.cli.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import student.management.cli.models.TeacherCreationRequest;
import student.management.core.TeacherService;
import student.management.data.Teacher;
@Controller
public class TeacherController {
private final TeacherService teacherService;
@Autowired
public TeacherController(TeacherService teacherService) {
this.teacherService = teacherService;
}
public void add(TeacherCreationRequest request){
System.out.println(teacherService.add(new Teacher(request.name(), request.degree())).toString());
}
}
package student.management.cli.models.course;
public record CourseCreationRequest(
String name,
int totalHours
) {
}
package student.management.cli.models.course;
public record CourseGradeRequest(
long courseID,
long studentID,
String gradeEnum
) {
}
package student.management.cli.models.course;
public record CourseInsertionRequest(
long courseID,
long entityID
) {
}
package student.management.api;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import student.management.api.controllers.CourseController;
import student.management.core.CourseService;
import student.management.core.models.AvgGradeDTO;
import student.management.core.models.StudentDTO;
import student.management.core.models.TeacherDTO;
import student.management.core.models.course.CourseCreationReq;
import student.management.core.models.course.CourseDTO;
import student.management.core.models.course.CourseStudentGradeReq;
import student.management.core.models.course.CourseStudentGradeRes;
import student.management.core.models.course.CourseWithAvgGradeResponse;
import student.management.data.Degree;
import student.management.data.GradeEnum;
import student.management.data.Student;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public class CourseControllerTest {
@InjectMocks
private CourseController courseController;
@Mock
private CourseService courseService;
@Autowired
private MockMvc mockMvc;
private static ObjectMapper objectMapper;
@BeforeAll
public static void preset(){
objectMapper = new ObjectMapper();
}
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(courseController).build();
}
@Test
public void testUpsertCourse() throws Exception {
CourseCreationReq inputCourseReq = new CourseCreationReq("New Course", 21);
CourseDTO outputCourseDTO = new CourseDTO("New Course", null, null);
Mockito.when(courseService.add(inputCourseReq)).thenReturn(outputCourseDTO);
String requestBody = objectMapper.writeValueAsString(inputCourseReq);
mockMvc.perform(MockMvcRequestBuilders.post("/api/courses")
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody))
.andExpectAll(
status().isCreated(),
content().json(objectMapper.writeValueAsString(outputCourseDTO))
);
}
@Test
public void testGetCourses() throws Exception {
List<CourseDTO> courseDTOList = new ArrayList<>();
courseDTOList.add(new CourseDTO("Course 1", null, null));
courseDTOList.add(new CourseDTO("Course 2", null, null));
Mockito.when(courseService.getAllCourses()).thenReturn(courseDTOList);
mockMvc.perform(MockMvcRequestBuilders.get("/api/courses"))
.andExpectAll(
status().isFound(),
content().json(objectMapper.writeValueAsString(courseDTOList))
);
}
@Test
public void testGetCoursesOrdered() throws Exception {
List<AvgGradeDTO> avgGradeDTOList = new ArrayList<>();
Student student1 = new Student();
Student student2 = new Student();
avgGradeDTOList.add(new AvgGradeDTO(1L, Map.of(student1, 4.60)));
avgGradeDTOList.add(new AvgGradeDTO(1L, Map.of(student2, 5.40)));
Mockito.when(courseService.getAverageGradeForStudentsPerCourse()).thenReturn(avgGradeDTOList);
mockMvc.perform(MockMvcRequestBuilders.get("/api/courses/asc-order"))
.andExpectAll(
status().isOk(),
content().json(objectMapper.writeValueAsString(avgGradeDTOList))
);
}
@Test
public void testGetCourseAvgGrade() throws Exception {
Long courseId = 1L;
CourseWithAvgGradeResponse avgGradeResponse = new CourseWithAvgGradeResponse("Math", 4.5);
Mockito.when(courseService.getAverageGrade(courseId)).thenReturn(avgGradeResponse);
mockMvc.perform(MockMvcRequestBuilders.get("/api/courses/{id}/avg-grade", courseId))
.andExpectAll(
status().isOk(),
content().json(objectMapper.writeValueAsString(avgGradeResponse))
);
}
@Test
public void testUpsertCourseTeacher() throws Exception {
Long courseId = 1L;
Long teacherId = 1L;
TeacherDTO teacher = new TeacherDTO("Miro", Degree.PHD);
CourseDTO courseDTO = new CourseDTO( "Course 1", teacher, null);
Mockito.when(courseService.assignTeacher(courseId, teacherId)).thenReturn(courseDTO);
mockMvc.perform(MockMvcRequestBuilders.patch("/api/courses/{id}/teacher", courseId)
.param("teacher_id", teacherId.toString()))
.andExpectAll(
status().isOk(),
content().json(objectMapper.writeValueAsString(courseDTO))
);
}
@Test
public void testUpsertCourseStudent() throws Exception {
Long courseId = 1L;
Long studentId = 1L;
StudentDTO student = new StudentDTO("Mario", 32);
CourseDTO courseDTO = new CourseDTO("Math", null, List.of(student));
Mockito.when(courseService.enrollStudent(courseId, studentId)).thenReturn(courseDTO);
mockMvc.perform(MockMvcRequestBuilders.patch("/api/courses/{id}/student", courseId)
.param("student_id", studentId.toString()))
.andExpectAll(
status().isOk(),
content().json(objectMapper.writeValueAsString(courseDTO))
);
}
@Test
public void testAddGradeToStudent() throws Exception {
Long courseId = 1L;
CourseStudentGradeReq gradeReq = new CourseStudentGradeReq(1L, GradeEnum.A);
CourseStudentGradeRes gradeRes = new CourseStudentGradeRes("Math", "Mario", GradeEnum.A);
Mockito.when(courseService.updateStudentGrades(courseId, gradeReq.studentId(), gradeReq.grade()))
.thenReturn(gradeRes);
String requestBody = objectMapper.writeValueAsString(gradeReq);
mockMvc.perform(MockMvcRequestBuilders.patch("/api/courses/{id}/student/grade", courseId)
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody))
.andExpectAll(
status().isOk(),
content().json(objectMapper.writeValueAsString(gradeRes))
);
}
}
package student.management.api;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import student.management.api.controllers.StudentController;
import student.management.core.StudentService;
import student.management.core.models.StudentDTO;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootApplication
public class StudentControllerTest {
@InjectMocks
private StudentController studentController;
@Mock
private StudentService studentService;
@Autowired
private MockMvc mockMvc;
private static ObjectMapper objectMapper;
@BeforeAll
public static void preset(){
objectMapper = new ObjectMapper();
}
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(studentController).build();
}
@Test
public void testUpsertStudent() throws Exception {
StudentDTO inputStudentDTO = new StudentDTO("New Student", 16);
Mockito.when(studentService.add(inputStudentDTO)).thenReturn(inputStudentDTO);
String reqResBody = objectMapper.writeValueAsString(inputStudentDTO);
mockMvc.perform(MockMvcRequestBuilders.post("/api/students")
.contentType(MediaType.APPLICATION_JSON)
.content(reqResBody))
.andExpectAll(
status().isCreated(),
content().json(reqResBody)
);
}
@Test
public void testGetStudents() throws Exception {
List<StudentDTO> studentDTOList = new ArrayList<>();
studentDTOList.add(new StudentDTO("Gosho", 12));
studentDTOList.add(new StudentDTO("Iliana", 16));
Mockito.when(studentService.getAll()).thenReturn(studentDTOList);
mockMvc.perform(MockMvcRequestBuilders.get("/api/students"))
.andExpectAll(
status().isFound(),
content().json(objectMapper.writeValueAsString(studentDTOList))
);
}
@Test
public void testGetStudent() throws Exception {
Long studentId = 1L;
StudentDTO studentDTO = new StudentDTO("Pesho", 35);
Mockito.when(studentService.get(studentId)).thenReturn(studentDTO);
mockMvc.perform(MockMvcRequestBuilders.get("/api/students/{id}", studentId))
.andExpectAll(
status().isFound(),
content().json(objectMapper.writeValueAsString(studentDTO))
);
}
}
\ No newline at end of file
package student.management.api;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import student.management.api.controllers.TeacherController;
import student.management.core.TeacherService;
import student.management.core.models.TeacherDTO;
import student.management.data.Degree;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootApplication
public class TeacherControllerTest {
@Mock
private TeacherService teacherService;
@InjectMocks
private TeacherController teacherController;
@Autowired
private MockMvc mockMvc;
private static ObjectMapper objectMapper;
@BeforeAll
public static void preset(){
objectMapper = new ObjectMapper();
}
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(teacherController).build();
}
@Test
public void testGetTeachers() throws Exception {
List<TeacherDTO> teacherDTOList = new ArrayList<>();
teacherDTOList.add(new TeacherDTO("Mario", Degree.BSc));
teacherDTOList.add(new TeacherDTO("Asen", Degree.MSc));
String teacherDTOListString = objectMapper.writeValueAsString(teacherDTOList);
Mockito.when(teacherService.getAll()).thenReturn(teacherDTOList);
mockMvc.perform(MockMvcRequestBuilders.get("/api/teachers"))
.andExpectAll(
status().isFound(),
content().json(teacherDTOListString)
);
}
@Test
public void testGetTeacher() throws Exception {
Long teacherId = 1L;
TeacherDTO teacherDTO = new TeacherDTO("Miro", Degree.BSc);
String reqResBody = objectMapper.writeValueAsString(teacherDTO);
Mockito.when(teacherService.get(teacherId)).thenReturn(teacherDTO);
mockMvc.perform(MockMvcRequestBuilders.get("/api/teachers/{id}", teacherId)
.contentType(MediaType.APPLICATION_JSON)
.content(reqResBody))
.andExpectAll(
status().isFound(),
content().json(reqResBody)
);
}
@Test
public void testUpsertTeacher() throws Exception {
TeacherDTO inputTeacherDTO = new TeacherDTO("New Teacher", Degree.BSc);
TeacherDTO outputTeacherDTO = new TeacherDTO( "New Teacher", Degree.BSc);
Mockito.when(teacherService.add(inputTeacherDTO)).thenReturn(outputTeacherDTO);
String requestBody = objectMapper.writeValueAsString(inputTeacherDTO);
String responseBody = objectMapper.writeValueAsString(outputTeacherDTO);
mockMvc.perform(MockMvcRequestBuilders.post("/api/teachers")
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody))
.andExpect(status().isCreated())
.andExpect(content().json(responseBody));
}
}
......@@ -29,6 +29,10 @@ dependencies {
// Spring Web sockets
implementation("org.springframework.boot:spring-boot-starter-web:3.1.2")
implementation("org.springframework.boot:spring-boot-starter-validation:3.1.2")
testImplementation("org.springframework.boot:spring-boot-starter-test:3.1.2")
// ModelMapper DTO
implementation ("org.mapstruct:mapstruct:1.5.5.Final")
annotationProcessor ("org.mapstruct:mapstruct-processor:1.4.2.Final")
}
tasks.named<Test>("test") {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment