Skip to content
Snippets Groups Projects
Commit 9415d38f authored by Jan Pokorný's avatar Jan Pokorný :lifter_tone2:
Browse files

Merge branch 'M2-certificate-responseEntity' into 'M2'

M2 certificate response entity

See merge request !24
parents b1b7adbe 2fb1424c
No related branches found
No related tags found
2 merge requests!31M2,!24M2 certificate response entity
Pipeline #
package org.fuseri.modulecertificate.service;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.persistence.EntityNotFoundException;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.fuseri.model.dto.certificate.CertificateCreateDto;
import org.fuseri.model.dto.certificate.CertificateDto;
import org.fuseri.model.dto.certificate.CertificateSimpleDto;
import org.fuseri.model.dto.common.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import java.util.List;
......@@ -35,9 +40,16 @@ public class CertificateController {
* @param certificateCreateDto Dto with data used for generating certificate
* @return CertificateDto with data of generated certificate
*/
@PostMapping("/generate")
public CertificateSimpleDto generate(@Valid @RequestBody CertificateCreateDto certificateCreateDto) {
return certificateFacade.generate(certificateCreateDto);
@Operation(summary = "Generate certificate",
description = "Generates certificate, saves it into database and returns certificate information and certificate file.")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "Certificate generated successfully."),
@ApiResponse(responseCode = "400", description = "Invalid input.")
})
@PostMapping
public ResponseEntity<CertificateSimpleDto> generate(@Valid @RequestBody CertificateCreateDto certificateCreateDto) {
var certificateSimpleDto = certificateFacade.generate(certificateCreateDto);
return ResponseEntity.status(HttpStatus.CREATED).body(certificateSimpleDto);
}
/**
......@@ -46,9 +58,18 @@ public class CertificateController {
* @param id ID of certificate to be retrieved
* @return CertificateDto with data of previously generated certificate with specified ID
*/
@GetMapping("/find")
public CertificateSimpleDto find(@RequestParam Long id) {
return certificateFacade.findById(id);
@Operation(summary = "Get a certificate by ID", description = "Returns a certificate with the specified ID.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Certificate with the specified ID retrieved successfully."),
@ApiResponse(responseCode = "404", description = "Certificate with the specified ID was not found.")
})
@GetMapping("/{id}")
public ResponseEntity<CertificateSimpleDto> find(@NotNull @PathVariable Long id) {
try {
return ResponseEntity.ok(certificateFacade.findById(id));
} catch (EntityNotFoundException e) {
return ResponseEntity.notFound().build();
}
}
/**
......@@ -58,9 +79,14 @@ public class CertificateController {
* @return List of CertificateDto objects with previously generated certificates
* for specified User.
*/
@Operation(summary = "Get certificates for user", description = "Returns certificates for given user in list.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved certificates"),
@ApiResponse(responseCode = "400", description = "Invalid input."),
})
@GetMapping("/findForUser")
public List<CertificateSimpleDto> findForUser(@RequestParam Long userId) {
return certificateFacade.findByUserId(userId);
public ResponseEntity<List<CertificateSimpleDto>> findForUser(@RequestParam Long userId) {
return ResponseEntity.ok(certificateFacade.findByUserId(userId));
}
/**
......@@ -71,9 +97,15 @@ public class CertificateController {
* @return List of CertificateDto objects with previously generated certificates
* for specified User and Course.
*/
@Operation(summary = "Get certificates for user and course",
description = "Returns certificates for given user and course in list.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved certificates"),
@ApiResponse(responseCode = "400", description = "Invalid input."),
})
@GetMapping("/findForUserAndCourse")
public List<CertificateSimpleDto> findForUserAndCourse(@RequestParam Long userId, @RequestParam Long courseId) {
return certificateFacade.findByUserIdAndCourseId(userId, courseId);
public ResponseEntity<List<CertificateSimpleDto>> findForUserAndCourse(@RequestParam Long userId, @RequestParam Long courseId) {
return ResponseEntity.ok(certificateFacade.findByUserIdAndCourseId(userId, courseId));
}
/**
......@@ -81,9 +113,14 @@ public class CertificateController {
*
* @param id Id of certificate to be deleted.
*/
@DeleteMapping("/delete")
public void delete(@RequestParam Long id) {
@Operation(summary = "Delete a certificate with specified ID", description = "Deletes a certificate with the specified ID.")
@ApiResponses(value = {
@ApiResponse(responseCode = "204", description = "Certificate with the specified ID deleted successfully."),
})
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@NotNull @PathVariable Long id) {
certificateFacade.deleteCertificate(id);
return ResponseEntity.noContent().build();
}
/**
......@@ -91,8 +128,13 @@ public class CertificateController {
*
* @return a Result object containing a list of CertificateDto objects and pagination information
*/
@GetMapping("/findAll")
public Page<CertificateSimpleDto> findAllCertificates(Pageable pageable) {
return certificateFacade.findAll(pageable);
@Operation(summary = "Get certificates in paginated format", description = "Returns certificates in paginated format.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved paginated certificates"),
@ApiResponse(responseCode = "400", description = "Invalid page number supplied"),
})
@GetMapping
public ResponseEntity<Page<CertificateSimpleDto>> findAllCertificates(Pageable pageable) {
return ResponseEntity.ok(certificateFacade.findAll(pageable));
}
}
......@@ -4,8 +4,10 @@ import org.fuseri.modulecertificate.Certificate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;
import java.util.List;
......@@ -22,7 +24,7 @@ public class CertificateService {
@Transactional(readOnly = true)
public Certificate findById(Long id) {
return certificateRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Certificate with id: " + id + " was not found."));
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Certificate with id: " + id + " was not found."));
}
@Transactional(readOnly = true)
......
......@@ -8,7 +8,7 @@ import org.fuseri.model.dto.course.LanguageTypeDto;
import org.fuseri.model.dto.course.ProficiencyLevelDto;
import org.fuseri.model.dto.user.AddressDto;
import org.fuseri.model.dto.user.UserDto;
import org.fuseri.modulecertificate.service.CertificateController;
import org.fuseri.modulecertificate.service.CertificateFacade;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
......@@ -35,15 +35,17 @@ class CertificateControllerTests {
private final UserDto USER = new UserDto("novakovat",
"novakova@gamil.com", "Tereza", "Nováková", new AddressDto());
private final CourseDto COURSE = new CourseDto("AJ1", 10,
private final CourseDto COURSE = new CourseDto(1L, "AJ1", 10,
LanguageTypeDto.ENGLISH, ProficiencyLevelDto.A1);
private final CertificateCreateDto certificateCreateDto = new CertificateCreateDto(USER, COURSE);
private final CertificateSimpleDto certificateDto = new CertificateSimpleDto(0L, USER.getId(),
Instant.now(), COURSE.getId(), "", "");
@Autowired
private MockMvc mockMvc;
@MockBean
private CertificateController certificateController;
private CertificateFacade certificateFacade;
private static String asJsonString(final Object obj) {
try {
......@@ -55,13 +57,13 @@ class CertificateControllerTests {
@Test
void generateCertificate() throws Exception {
Mockito.when(certificateController.generate(ArgumentMatchers.any(CertificateCreateDto.class)))
Mockito.when(certificateFacade.generate(ArgumentMatchers.any(CertificateCreateDto.class)))
.thenReturn(certificateDto);
mockMvc.perform(post("/certificates/generate")
mockMvc.perform(post("/certificates")
.content(asJsonString(certificateCreateDto))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$.id").value(certificateDto.getId()))
.andExpect(jsonPath("$.userId").value(certificateDto.getUserId()))
.andExpect(jsonPath("$.generatedAt").value(certificateDto.getGeneratedAt().toString()))
......@@ -96,22 +98,22 @@ class CertificateControllerTests {
@Test
void findCertificate() throws Exception {
Mockito.when(certificateController.find(ArgumentMatchers.anyLong())).thenReturn(certificateDto);
Mockito.when(certificateFacade.findById(ArgumentMatchers.anyLong())).thenReturn(certificateDto);
mockMvc.perform(get("/certificates/find").param("id", certificateDto.getId().toString()))
mockMvc.perform(get("/certificates/" + certificateDto.getId()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(certificateDto.getId()));
}
@Test
void findCertificateWithoutId() throws Exception {
mockMvc.perform(get("/certificates/find"))
mockMvc.perform(get("/certificates/"))
.andExpect(status().is4xxClientError());
}
@Test
void findCertificatesForUser() throws Exception {
Mockito.when(certificateController.findForUser(ArgumentMatchers.anyLong())).thenReturn(List.of(certificateDto));
Mockito.when(certificateFacade.findByUserId(ArgumentMatchers.anyLong())).thenReturn(List.of(certificateDto));
mockMvc.perform(get("/certificates/findForUser").param("userId", "0"))
.andExpect(status().isOk())
......@@ -127,7 +129,7 @@ class CertificateControllerTests {
@Test
void findCertificateIdForUserAndCourse() throws Exception {
Mockito.when(certificateController.findForUserAndCourse(ArgumentMatchers.anyLong(),
Mockito.when(certificateFacade.findByUserIdAndCourseId(ArgumentMatchers.anyLong(),
ArgumentMatchers.anyLong()))
.thenReturn(List.of(certificateDto));
......@@ -161,25 +163,24 @@ class CertificateControllerTests {
@Test
void deleteCertificate() throws Exception {
Mockito.doNothing().when(certificateController).delete(ArgumentMatchers.anyLong());
Mockito.doNothing().when(certificateFacade).deleteCertificate(ArgumentMatchers.anyLong());
mockMvc.perform(delete("/certificates/delete")
.param("id", String.valueOf(0L)))
.andExpect(status().isOk());
mockMvc.perform(delete("/certificates/" + 0L))
.andExpect(status().is2xxSuccessful());
}
@Test
void deleteCertificateWithoutParam() throws Exception {
mockMvc.perform(delete("/certificates/delete"))
mockMvc.perform(delete("/certificates/"))
.andExpect(status().is4xxClientError());
}
@Test
void findAllCertificates() throws Exception {
Mockito.when(certificateController.findAllCertificates(ArgumentMatchers.any(Pageable.class)))
Mockito.when(certificateFacade.findAll(ArgumentMatchers.any(Pageable.class)))
.thenReturn(Page.empty(PageRequest.of(0, 1)));
mockMvc.perform(get("/certificates/findAll")
mockMvc.perform(get("/certificates")
.param("page", "0")
.param("size", "10"))
.andExpect(status().isOk())
......@@ -189,10 +190,10 @@ class CertificateControllerTests {
@Test
void findAllCertificatesWithoutParam() throws Exception {
Mockito.when(certificateController.findAllCertificates(ArgumentMatchers.any(Pageable.class)))
Mockito.when(certificateFacade.findAll(ArgumentMatchers.any(Pageable.class)))
.thenReturn(Page.empty(PageRequest.of(0, 1)));
mockMvc.perform(get("/certificates/findAll"))
mockMvc.perform(get("/certificates"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.content").isEmpty());
......
......@@ -34,7 +34,7 @@ import static org.mockito.Mockito.when;
final class CertificateFacadeTests {
private final UserDto USER = new UserDto("novakovat",
"novakova@gamil.com", "Tereza", "Nováková", new AddressDto());
private final CourseDto COURSE = new CourseDto("AJ1", 10,
private final CourseDto COURSE = new CourseDto(1L,"AJ1", 10,
LanguageTypeDto.ENGLISH, ProficiencyLevelDto.A1);
private final CertificateCreateDto certificateCreateDto = new CertificateCreateDto(USER, COURSE);
private final CertificateSimpleDto certificateDto = new CertificateSimpleDto(0L, USER.getId(),
......
......@@ -25,7 +25,7 @@ final class CertificateMapperTests {
private final UserDto USER = new UserDto("novakovat",
"novakova@gamil.com", "Tereza", "Nováková", new AddressDto());
private final CourseDto COURSE = new CourseDto("AJ1", 10,
private final CourseDto COURSE = new CourseDto(1L,"AJ1", 10,
LanguageTypeDto.ENGLISH, ProficiencyLevelDto.A1);
private final Instant instant = Instant.now();
private final String fileName = "fileName";
......@@ -68,7 +68,7 @@ final class CertificateMapperTests {
var createdCertificate = certificateMapper.mapToCertificate(certificateCreateDto);
Assertions.assertEquals(createdCertificate.getUserId(), certificateDto.getUserId());
Assertions.assertTrue(createdCertificate.getGeneratedAt().isBefore(Instant.now()));
Assertions.assertNotNull(createdCertificate.getGeneratedAt());
Assertions.assertEquals(createdCertificate.getCourseId(), certificateDto.getCourseId());
Assertions.assertNull(createdCertificate.getCertificateFile());
Assertions.assertNull(createdCertificate.getCertificateFileName());
......
......@@ -7,10 +7,8 @@ import org.fuseri.model.dto.user.AddressDto;
import org.fuseri.model.dto.user.UserDto;
import org.fuseri.modulecertificate.service.CertificateRepository;
import org.fuseri.modulecertificate.service.CertificateService;
import org.fuseri.modulecertificate.service.ResourceNotFoundException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.stubbing.OngoingStubbing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
......@@ -18,6 +16,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.server.ResponseStatusException;
import java.time.Instant;
import java.util.Collections;
......@@ -37,7 +36,7 @@ final class CertificateServiceTests {
private final UserDto USER = new UserDto("novakovat",
"novakova@gamil.com", "Tereza", "Nováková", new AddressDto());
private final CourseDto COURSE = new CourseDto("AJ1", 10,
private final CourseDto COURSE = new CourseDto(1L, "AJ1", 10,
LanguageTypeDto.ENGLISH, ProficiencyLevelDto.A1);
private final Certificate certificate = new Certificate(USER.getId(),
Instant.now(), COURSE.getId(), "file", "fileName");
......@@ -57,7 +56,7 @@ final class CertificateServiceTests {
void notFoundById() {
when(certificateRepository.findById(certificate.getId())).thenReturn(Optional.empty());
Assertions.assertThrows(ResourceNotFoundException.class, () -> certificateService.findById(certificate.getId()));
Assertions.assertThrows(ResponseStatusException.class, () -> certificateService.findById(certificate.getId()));
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment