Skip to content
Snippets Groups Projects
Commit 48a8f879 authored by Filip Bugoš's avatar Filip Bugoš
Browse files

Merge branch 'issue-15' into 'milestone-1'

openAPI documentation for user WIP

See merge request !9
parents 8cc28a3f e1aba639
No related branches found
No related tags found
2 merge requests!25Milestone 1,!9openAPI documentation for user WIP
Pipeline #
package cz.muni.fi.pa165.core.common;
import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
import cz.muni.fi.pa165.model.dto.common.Result;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.springframework.data.domain.Page;
import java.util.List;
......@@ -12,7 +16,6 @@ public interface DomainMapper<T extends DomainObject, S extends DomainObjectDto>
List<S> toDtoList(List<T> entities);
/*
@Mappings({
@Mapping(target = "total", expression = "java(source.getTotalElements())"),
@Mapping(target = "page", expression = "java(source.getNumber())"),
......@@ -20,5 +23,5 @@ public interface DomainMapper<T extends DomainObject, S extends DomainObjectDto>
@Mapping(target = "items", expression = "java(toDtoList(source.getContent()))")
})
Result<S> toResult(Page<T> source);
*/
}
package cz.muni.fi.pa165.core.user;
import cz.muni.fi.pa165.model.dto.common.Result;
import cz.muni.fi.pa165.model.dto.user.UserCreateDto;
import cz.muni.fi.pa165.model.dto.user.UserDto;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.List;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
@RequestMapping("/api/user")
public class UserController {
private final UserFacade userFacade;
private final UserService service;
private final UserMapper mapper;
@Autowired
public UserController(UserFacade userFacade) {
this.userFacade = userFacade;
}
@Autowired
public UserController(UserService service, UserMapper mapper) {
this.service = service;
this.mapper = mapper;
@Operation(
summary = "Find user by ID",
description = "Returns a single user",
tags = {"user"})
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "User found",
content = {
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UserDto.class))
}),
@ApiResponse(responseCode = "404", description = "User not found", content = @Content)
})
@GetMapping("/{id}")
public UserDto findById(
@Parameter(description = "ID of user to be searched") @PathVariable String id) {
return userFacade.findById(id);
}
@GetMapping
public List<UserDto> findAll() {
return service.findAll().stream().map(mapper::toDto).toList();
@Operation(
summary = "Create user",
description = "Creates a new user",
tags = {"user"})
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "User created",
content = {
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UserDto.class))
}),
@ApiResponse(responseCode = "400", description = "Invalid input", content = @Content),
@ApiResponse(
responseCode = "409",
description = "User with the same name already exists",
content = @Content)
})
@PostMapping
public UserDto create(
@Parameter(description = "User to be created") @RequestBody UserCreateDto userCreateDto) {
return userFacade.create(userCreateDto);
}
@GetMapping("/{id}")
public UserDto find(@PathVariable String id) {
return mapper.toDto(service.find(id));
@Operation(
summary = "Get all users",
description = "Returns all users",
tags = {"user"})
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "Users found",
content = {
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Result.class))
})
})
@GetMapping
public Result<UserDto> findAll(
@Parameter(description = "Page number of results to retrieve") @RequestParam int page) {
return userFacade.findAll(page);
}
@PostMapping
public UserDto create(@RequestBody UserCreateDto dto) {
return mapper.toDto(service.create(mapper.fromCreateDto(dto)));
}
@PutMapping("/{id}")
@Operation(summary = "Update a user by ID")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "User updated successfully"),
@ApiResponse(responseCode = "400", description = "Invalid input"),
@ApiResponse(responseCode = "404", description = "User not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
public UserDto update(
@Parameter(description = "ID of the user to be updated") @PathVariable String id,
@RequestBody @Valid UserCreateDto userCreateDto) {
return userFacade.update(userCreateDto, id);
}
// @GetMapping
// public Result<UserDto> findAll(@RequestParam int page) {
// return mapper.toResult(service.findAll(page));
// }
@DeleteMapping("/{id}")
@Operation(summary = "Delete a user by ID")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "User deleted successfully"),
@ApiResponse(responseCode = "404", description = "User not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
public UserDto delete(
@Parameter(description = "ID of the user to be deleted") @PathVariable String id) {
return userFacade.delete(id);
}
}
package cz.muni.fi.pa165.core.user;
import cz.muni.fi.pa165.model.dto.common.Result;
import cz.muni.fi.pa165.model.dto.user.UserCreateDto;
import cz.muni.fi.pa165.model.dto.user.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
@Transactional
public class UserFacade {
private final UserService userService;
private final UserMapper userMapper;
@Autowired
public UserFacade(UserService userService, UserMapper userMapper) {
this.userService = userService;
this.userMapper = userMapper;
}
@Transactional(readOnly = true)
public UserDto findById(String id) {
return userMapper.toDto(userService.findById(id));
}
@Transactional(readOnly = true)
public Result<UserDto> findAll(int page) {
return userMapper.toResult(userService.findAllPageableInt(page));
}
@Transactional(readOnly = true)
public UserDto create(UserCreateDto userCreateDto) {
return userMapper.toDto(userService.create(userMapper.fromCreateDto(userCreateDto)));
}
@Transactional
public UserDto delete(String id) {
return userMapper.toDto(userService.deleteById(id));
}
@Transactional
public UserDto update(UserCreateDto userUpdatedDto, String id) {
return userMapper.toDto(userService.update(userMapper.fromCreateDto(userUpdatedDto), id));
}
}
package cz.muni.fi.pa165.core.user;
import cz.muni.fi.pa165.core.common.DomainMapper;
import cz.muni.fi.pa165.core.device.Device;
import cz.muni.fi.pa165.model.dto.common.Result;
import cz.muni.fi.pa165.model.dto.device.DeviceUpdateDto;
import cz.muni.fi.pa165.model.dto.user.UserCreateDto;
import cz.muni.fi.pa165.model.dto.user.UserDto;
import org.mapstruct.Mapper;
......@@ -9,4 +12,5 @@ import org.mapstruct.Mapper;
public interface UserMapper extends DomainMapper<User, UserDto> {
User fromCreateDto(UserCreateDto dto);
}
package cz.muni.fi.pa165.core.user;
import cz.muni.fi.pa165.core.device.Device;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, String> {}
public interface UserRepository extends JpaRepository<User, String> {
@Modifying
@Query("UPDATE User u set u.username= :#{#user.username}, u.password= :#{#user.password}, u.lastName= :#{#user.lastName}, u.firstName= :#{#user.firstName}, u.email= :#{#user.email} where u.id = :#{#id}")
int update(@Param("user") User user, @Param("id") String id);
}
......@@ -7,8 +7,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class UserService extends DomainService<User> {
......@@ -20,14 +18,33 @@ public class UserService extends DomainService<User> {
}
@Transactional(readOnly = true)
public User find(String id) {
public User findById(String id) {
return repository
.findById(id)
.orElseThrow(() -> new EntityNotFoundException("User '" + id + "' not found."));
}
@Transactional(readOnly = true)
public List<User> findAll() {
return repository.findAll();
public void deleteAll() {
repository.deleteAll();
}
@Transactional(readOnly = true)
public User deleteById(String id) {
User result = findById(id);
if (result == null)
throw new EntityNotFoundException("User '" + id + "' not found.");
repository.deleteById(id);
return result;
}
@Transactional(readOnly = true)
public User update(User user, String id) {
int result = repository.update(user, id);
if (result != 1) {
throw new EntityNotFoundException("User '" + id + "' not found.");
}
return findById(id);
}
}
package cz.muni.fi.pa165.core.user;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
@WebMvcTest(controllers = UserController.class)
public class UserControllerTest {
@Autowired private MockMvc mockMvc;
@Autowired private ObjectMapper objectMapper;
@MockBean private UserService service;
@BeforeEach
public void setUp() {
List.of(
new User()
.builder()
.firstName("Marek")
.lastName("Pavel")
.email("marek@gmail.cz")
.userType(UserType.NORMAL)
.password("adminadmin")
.build(),
new User()
.builder()
.firstName("John")
.lastName("Doe")
.email("john.doe@gmail.com")
.userType(UserType.NORMAL)
.password("password123")
.build(),
new User()
.builder()
.firstName("Jane")
.lastName("Doe")
.email("jane.doe@gmail.com")
.userType(UserType.ADMIN)
.password("qwertyuiop")
.build())
.stream()
.forEach(service::create);
}
@AfterEach
public void dropData() {
service.deleteAll();
}
/*
@Test
void getUserTest() throws Exception {
for (User user : service.findAll()) {
mockMvc.perform(get("/api/user/" + user.getId())).andExpect(status().isOk());
.andExpect(content().json("{\"id\":\"" + user.getId()
+ "\",\"username\":\""
+ user.getUsername()
+ "\",\"email\":\""
+ user.getEmail()
+ "\",\"firstName\":\""
+ user.getFirstName()
+ "\",\"lastName\":\""
+ user.getLastName()
+ "\"}"));
*
}
}
*/
}
package cz.muni.fi.pa165.model.dto.common;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class Result<T extends DomainObjectDto> {
private long total;
private int page;
private int pageSize;
private List<T> items;
}
......@@ -91,28 +91,6 @@
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>com.theoryinpractise</groupId>
<artifactId>googleformatter-maven-plugin</artifactId>
<version>1.7.3</version>
<executions>
<execution>
<id>reformat-sources</id>
<configuration>
<includeStale>false</includeStale>
<style>GOOGLE</style>
<filterModified>false</filterModified>
<skip>false</skip>
<fixImports>false</fixImports>
<maxLineLength>100</maxLineLength>
</configuration>
<goals>
<goal>format</goal>
</goals>
<phase>process-sources</phase>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
......
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