Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • xpokorn8/sprachschulsystem
1 result
Select Git revision
Show changes
Commits on Source (11)
Showing
with 420 additions and 109 deletions
......@@ -33,6 +33,6 @@ public class CertificateDto extends DomainObjectDto {
private CertificateFileDto certificateFile;
public CertificateDto() {
setId("0");
setId(0L);
}
}
package org.fuseri.model.dto.certificate;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import org.fuseri.model.dto.common.DomainObjectDto;
import java.time.Instant;
/**
* This class represents a Data Transfer Object (DTO) for Certificate entities.
* It is used to transfer Certificate data between different layers of the application.
* It extends the DomainObjectDto class and includes additional Certificate-specific fields.
*/
@Getter
@Setter
public class CertificateSimpleDto extends DomainObjectDto {
@NotBlank
@NotNull
private Long userId;
@NotBlank
@NotNull
private Instant generatedAt;
@NotBlank
@NotNull
private Long courseId;
@NotBlank
@NotNull
private String certificateFile;
@NotBlank
@NotNull
private String certificateFileName;
public CertificateSimpleDto(Long id, Long userId, Instant generatedAt, Long courseId, String certificateFile, String certificateFileName) {
this.setId(id);
this.userId = userId;
this.generatedAt = generatedAt;
this.courseId = courseId;
this.certificateFile = certificateFile;
this.certificateFileName = certificateFileName;
}
}
package org.fuseri.model.dto.common;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
......@@ -9,7 +8,6 @@ import lombok.Setter;
@Setter
public abstract class DomainObjectDto {
@NotBlank
@NotNull
private String id;
private Long id;
}
......@@ -44,7 +44,7 @@ public class CourseDto extends DomainObjectDto {
private List<String> studentIds;
public CourseDto(String name, Integer capacity, LanguageTypeDto languageTypeDto, ProficiencyLevelDto proficiencyLevelDto) {
setId("0");
setId(0L);
this.name = name;
this.capacity = capacity;
this.languageTypeDto = languageTypeDto;
......
......@@ -21,7 +21,7 @@ public class UserDto extends DomainObjectDto {
public UserDto(String username, String email, String firstName, String lastName, AddressDto address) {
setId("0");
setId(0L);
this.username = username;
this.email = email;
this.firstName = firstName;
......
......@@ -61,6 +61,18 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
<build>
......
package org.fuseri.modulecertificate;
import jakarta.persistence.*;
import java.io.Serializable;
import java.time.Instant;
import java.util.Objects;
@Entity
@Table(name = "certificate")
public class Certificate implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_certificate")
private Long id;
@Column(name = "id_user")
private Long userId;
@Column(name = "generatedAt")
@Temporal(TemporalType.TIMESTAMP)
private Instant generatedAt;
@Column(name = "id_course")
private Long courseId;
@Column(name = "certificate_file")
private String certificateFile;
@Column(name = "certificate_file_name")
private String certificateFileName;
public Certificate() {
}
public Certificate(Long userId, Instant generatedAt, Long courseId, String certificateFile, String certificateFileName) {
this.userId = userId;
this.generatedAt = generatedAt;
this.courseId = courseId;
this.certificateFile = certificateFile;
this.certificateFileName = certificateFileName;
}
public Long getId() {
return id;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Instant getGeneratedAt() {
return generatedAt;
}
public void setGeneratedAt(Instant generatedAt) {
this.generatedAt = generatedAt;
}
public Long getCourseId() {
return courseId;
}
public void setCourseId(Long courseId) {
this.courseId = courseId;
}
public String getCertificateFile() {
return certificateFile;
}
public void setCertificateFile(String certificateFile) {
this.certificateFile = certificateFile;
}
public String getCertificateFileName() {
return certificateFileName;
}
public void setCertificateFileName(String certificateFileName) {
this.certificateFileName = certificateFileName;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Certificate certificate)) {
return false;
}
return Objects.equals(getUserId(), certificate.getUserId())
&& Objects.equals(getGeneratedAt(), certificate.getGeneratedAt())
&& Objects.equals(getCourseId(), certificate.getCourseId())
&& Objects.equals(getCertificateFile(), certificate.getCertificateFile())
&& Objects.equals(getCertificateFileName(), certificate.getCertificateFileName());
}
@Override
public int hashCode() {
return Objects.hash(getUserId(), getGeneratedAt(), getCourseId(), getCertificateFile(), getCertificateFileName());
}
}
......@@ -3,8 +3,11 @@ package org.fuseri.modulecertificate.service;
import jakarta.validation.Valid;
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.web.bind.annotation.*;
import java.util.List;
......@@ -18,10 +21,14 @@ import java.util.List;
@RequestMapping("/certificates")
public class CertificateController {
private final CertificateFacade certificateFacade;
@Autowired
public CertificateController() {
public CertificateController(CertificateFacade certificateFacade) {
this.certificateFacade = certificateFacade;
}
/**
* Generates certificate for specified user and course.
*
......@@ -29,8 +36,8 @@ public class CertificateController {
* @return CertificateDto with data of generated certificate
*/
@PostMapping("/generate")
public CertificateDto generate(@Valid @RequestBody CertificateCreateDto certificateCreateDto) {
return new CertificateDto();
public CertificateSimpleDto generate(@Valid @RequestBody CertificateCreateDto certificateCreateDto) {
return certificateFacade.generate(certificateCreateDto);
}
/**
......@@ -40,8 +47,8 @@ public class CertificateController {
* @return CertificateDto with data of previously generated certificate with specified ID
*/
@GetMapping("/find")
public CertificateDto find(@RequestParam String id) {
return new CertificateDto();
public CertificateSimpleDto find(@RequestParam Long id) {
return certificateFacade.findById(id);
}
/**
......@@ -52,8 +59,8 @@ public class CertificateController {
* for specified User.
*/
@GetMapping("/findForUser")
public List<CertificateDto> findForUser(@RequestParam String userId) {
return List.of(new CertificateDto());
public List<CertificateSimpleDto> findForUser(@RequestParam Long userId) {
return certificateFacade.findByUserId(userId);
}
/**
......@@ -62,11 +69,11 @@ public class CertificateController {
* @param userId ID of user to retrieve certificates for.
* @param courseId ID of course to retrieve certificates for.
* @return List of CertificateDto objects with previously generated certificates
* for specified User.
* for specified User and Course.
*/
@GetMapping("/getId")
public String getId(@RequestParam String userId, @RequestParam String courseId) {
return "0";
@GetMapping("/findForUserAndCourse")
public List<CertificateSimpleDto> findForUserAndCourse(@RequestParam Long userId, @RequestParam Long courseId) {
return certificateFacade.findByUserIdAndCourseId(userId, courseId);
}
/**
......@@ -75,17 +82,17 @@ public class CertificateController {
* @param id Id of certificate to be deleted.
*/
@DeleteMapping("/delete")
public void delete(@RequestParam String id) {
public void delete(@RequestParam Long id) {
certificateFacade.deleteCertificate(id);
}
/**
* Find certificates and return them in a paginated format
*
* @param page the page number of the certificates to retrieve
* @return a Result object containing a list of CertificateDto objects and pagination information
*/
@GetMapping("/findAll")
public Result<CertificateDto> findAllCertificates(@RequestParam int page) {
return new Result<>();
public Page<CertificateSimpleDto> findAllCertificates(@RequestBody Pageable pageable) {
return certificateFacade.findAll(pageable);
}
}
package org.fuseri.modulecertificate.service;
import org.fuseri.model.dto.certificate.CertificateCreateDto;
import org.fuseri.model.dto.certificate.CertificateDto;
import org.fuseri.model.dto.certificate.CertificateSimpleDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class CertificateFacade {
private final CertificateService certificateService;
private final CertificateMapper certificateMapper;
@Autowired
public CertificateFacade(CertificateService certificateService, CertificateMapper certificateMapper) {
this.certificateService = certificateService;
this.certificateMapper = certificateMapper;
}
@Cacheable(cacheNames = "certificates", key = "#id")
@Transactional(readOnly = true)
public CertificateSimpleDto findById(Long id) {
return certificateMapper.mapToSimpleDto(certificateService.findById(id));
}
@Transactional()
public CertificateSimpleDto generate(CertificateCreateDto certificateCreateDto) {
return certificateMapper.mapToSimpleDto(certificateService.save(certificateMapper.mapToCertificate(certificateCreateDto)));
}
@Cacheable(cacheNames = "certificates", key = "#userId")
@Transactional(readOnly = true)
public List<CertificateSimpleDto> findByUserId(Long userId) {
return certificateMapper.mapToList(certificateService.findByUserId(userId));
}
@Cacheable(cacheNames = "certificates", key = "#userId")
@Transactional(readOnly = true)
public List<CertificateSimpleDto> findByUserIdAndCourseId(Long userId, Long courseId) {
return certificateMapper.mapToList(certificateService.findByUserIdAndCourseId(userId, courseId));
}
@Transactional(readOnly = true)
public Page<CertificateSimpleDto> findAll(Pageable pageable) {
return certificateMapper.mapToPageDto(certificateService.findAll(pageable));
}
@Transactional(readOnly = true)
public void deleteCertificate(Long certificateId) {
certificateService.delete(certificateId);
}
}
package org.fuseri.modulecertificate.service;
import org.fuseri.model.dto.certificate.CertificateCreateDto;
import org.fuseri.model.dto.certificate.CertificateDto;
import org.fuseri.model.dto.certificate.CertificateSimpleDto;
import org.fuseri.modulecertificate.Certificate;
import org.mapstruct.Mapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import java.time.Instant;
import java.util.List;
@Mapper(componentModel = "spring")
public interface CertificateMapper {
default CertificateSimpleDto mapToSimpleDto(Certificate certificate)
{
if ( certificate == null ) {
return null;
}
return new CertificateSimpleDto(
certificate.getId(),
certificate.getUserId(),
certificate.getGeneratedAt(),
certificate.getCourseId(),
certificate.getCertificateFile(),
certificate.getCertificateFileName());
}
default Certificate mapToCertificate(CertificateCreateDto certificateCreateDto)
{
if ( certificateCreateDto == null ) {
return null;
}
return new Certificate(certificateCreateDto.getUser().getId(),
Instant.now(),
certificateCreateDto.getCourse().getId(),
null,
null);
}
List<CertificateSimpleDto> mapToList(List<Certificate> certificates);
default Page<CertificateSimpleDto> mapToPageDto(Page<Certificate> certificates) {
return new PageImpl<>(mapToList(certificates.getContent()), certificates.getPageable(), certificates.getTotalPages());
}
}
package org.fuseri.modulecertificate.service;
import org.fuseri.modulecertificate.Certificate;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CertificateRepository extends JpaRepository<Certificate, Long> {
@Query("SELECT c FROM Certificate c WHERE c.userId = ?1")
List<Certificate> findCertificateByUserId(Long userId);
@Query("SELECT c FROM Certificate c WHERE c.userId = ?1 and c.courseId = ?2")
List<Certificate> findCertificateByUserIdAndCourseId(Long userId, Long courseId);
}
package org.fuseri.modulecertificate.service;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class CertificateService {
private final CertificateRepository certificateRepository;
@Autowired
public CertificateService(CertificateRepository certificateRepository) {
this.certificateRepository = certificateRepository;
}
@Transactional(readOnly = true)
public Certificate findById(Long id) {
return certificateRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Certificate with id: " + id + " was not found."));
}
@Transactional(readOnly = true)
public List<Certificate> findByUserId(Long userId) {
return certificateRepository.findCertificateByUserId(userId);
}
@Transactional(readOnly = true)
public List<Certificate> findByUserIdAndCourseId(Long userId, Long courseId) {
return certificateRepository.findCertificateByUserIdAndCourseId(userId, courseId);
}
@Transactional(readOnly = true)
public Certificate save(Certificate certificate) {
return certificateRepository.save(certificate);
}
@Transactional(readOnly = true)
public void delete(Long certificateId) {
certificateRepository.deleteById(certificateId);
}
@Transactional(readOnly = true)
public Page<Certificate> findAll(Pageable pageable) {
return certificateRepository.findAll(pageable);
}
}
package org.fuseri.modulecertificate.service;
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException() {
}
public ResourceNotFoundException(String message) {
super(message);
}
public ResourceNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public ResourceNotFoundException(Throwable cause) {
super(cause);
}
public ResourceNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
server.port=5001
\ No newline at end of file
server.port=5001
spring.jpa.open-in-view=false
spring.datasource.url=jdbc:h2:mem:social-network;MODE=PostgreSQL
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=SedaQ-app
spring.datasource.password=$argon2id$v=19$m=16,t=2,p=1$YmF0bWFuYmF0bWFu$MdHYB359HdivAb9J6CaILw
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# showing SQL is generally good practice for running project locally to check whether there is not an issue with implementation of JPA methods.
spring.jpa.show-sql=true
\ No newline at end of file
......@@ -9,12 +9,16 @@ import org.fuseri.model.dto.course.ProficiencyLevelDto;
import org.fuseri.model.dto.user.AddressDto;
import org.fuseri.model.dto.user.UserDto;
import org.junit.jupiter.api.Test;
import org.springdoc.core.converters.models.Pageable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
......@@ -72,9 +76,9 @@ class CertificateControllerTests {
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
String id = objectMapper.readValue(response, CertificateDto.class).getId();
Long id = objectMapper.readValue(response, CertificateDto.class).getId();
mockMvc.perform(get("/certificates/find").param("id", id))
mockMvc.perform(get("/certificates/find").param("id", id.toString()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(id));
}
......@@ -101,30 +105,30 @@ class CertificateControllerTests {
@Test
void findCertificateIdForUserAndCourse() throws Exception {
mockMvc.perform(get("/certificates/getId")
mockMvc.perform(get("/certificates/findForUserAndCourse")
.param("userId", "0")
.param("courseId", "0"))
.andExpect(status().isOk())
.andExpect(content().string("0"));
.andExpect(content().string("[]"));
}
@Test
void findCertificateIdWithoutUserId() throws Exception {
mockMvc.perform(get("/certificates/getId")
mockMvc.perform(get("/certificates/findForUserAndCourse")
.param("courseId", "0"))
.andExpect(status().is4xxClientError());
}
@Test
void findCertificateIdWithoutCourseId() throws Exception {
mockMvc.perform(get("/certificates/getId")
mockMvc.perform(get("/certificates/findForUserAndCourse")
.param("userId", "0"))
.andExpect(status().is4xxClientError());
}
@Test
void findCertificateIdWithoutParams() throws Exception {
mockMvc.perform(get("/certificates/getId"))
mockMvc.perform(get("/certificates/findForUserAndCourse"))
.andExpect(status().is4xxClientError());
}
......@@ -144,8 +148,14 @@ class CertificateControllerTests {
@Test
void findAllCertificates() throws Exception {
mockMvc.perform(post("/certificates/generate")
.content(asJsonString(new CertificateCreateDto(USER, COURSE)))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
mockMvc.perform(get("/certificates/findAll")
.param("page", "1"))
.content("{ \"page\": 0, \"size\": 1, \"sort\": []}")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
......
package org.fuseri.modulecertificate;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ModuleCertificateApplicationTests {
@Test
void contextLoads() {
}
}
package org.fuseri.modulecertificate;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.fuseri.model.dto.certificate.CertificateCreateDto;
import org.fuseri.model.dto.certificate.CertificateDto;
import org.fuseri.model.dto.course.CourseDto;
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.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
class ModuleCertificateCertificateControllerTests {
@Autowired
private MockMvc mockMvc;
@Autowired
ObjectMapper objectMapper;
@Test
void generateCertificate() throws Exception {
CertificateDto expectedResponse = new CertificateDto();
String response = mockMvc.perform(post("/certificates/generate")
.content(asJsonString(new CertificateCreateDto(
new UserDto("novakovat","novakova@gamil.com", "Tereza",
"Nováková", new AddressDto()),
new CourseDto("AJ1", 10, LanguageTypeDto.ENGLISH, ProficiencyLevelDto.A1))))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString();
CertificateController certificateController = objectMapper.readValue(response, CertificateController.class);
assertThat("response", certificateController.find("0"), is(instanceOf(expectedResponse.getClass())));
}
@Test
void deleteCertificate() throws Exception {
String response = mockMvc.perform(delete("/certificates/delete")
.param("id", "1"))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString();
}
public static String asJsonString(final Object obj) {
try {
return new ObjectMapper().writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}