diff --git a/library-api-users-service/pom.xml b/library-api-users-service/pom.xml index 303f385..baab04c 100644 --- a/library-api-users-service/pom.xml +++ b/library-api-users-service/pom.xml @@ -103,6 +103,10 @@ 5.11.0 test + + org.springframework.security + spring-security-test + diff --git a/library-api-users-service/src/main/java/dev/earlspilner/users/configuration/ResponseHandler.java b/library-api-users-service/src/main/java/dev/earlspilner/users/configuration/ResponseHandler.java index c28d865..14d2521 100644 --- a/library-api-users-service/src/main/java/dev/earlspilner/users/configuration/ResponseHandler.java +++ b/library-api-users-service/src/main/java/dev/earlspilner/users/configuration/ResponseHandler.java @@ -13,7 +13,17 @@ @Component public class ResponseHandler { - public ResponseEntity handleResult(Result result) { + public ResponseEntity handle201Result(Result result) { + if (result instanceof Success success) { + return new ResponseEntity<>(success.value(), HttpStatus.CREATED); + } else if (result instanceof Failure failure) { + return new ResponseEntity<>(failure.toProblemDetail(), HttpStatus.BAD_REQUEST); + } + + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + + public ResponseEntity handle200Result(Result result) { if (result instanceof Success success) { return new ResponseEntity<>(success.value(), HttpStatus.OK); } else if (result instanceof Failure failure) { @@ -23,7 +33,7 @@ public ResponseEntity handleResult(Result result) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } - public ResponseEntity handleResult(Result result, HttpStatus httpStatus) { + public ResponseEntity handle200Result(Result result, HttpStatus httpStatus) { if (result instanceof Success success) { return new ResponseEntity<>(success.value(), HttpStatus.OK); } else if (result instanceof Failure failure) { diff --git a/library-api-users-service/src/main/java/dev/earlspilner/users/rest/controller/UserRestController.java b/library-api-users-service/src/main/java/dev/earlspilner/users/rest/controller/UserRestController.java index 1f72b67..e5dc167 100644 --- a/library-api-users-service/src/main/java/dev/earlspilner/users/rest/controller/UserRestController.java +++ b/library-api-users-service/src/main/java/dev/earlspilner/users/rest/controller/UserRestController.java @@ -34,14 +34,14 @@ public UserRestController(UserService userService, ResponseHandler responseHandl @ResponseStatus(HttpStatus.CREATED) public ResponseEntity addUser(@Valid @RequestBody UserDto userDto) { Result result = this.userService.saveUser(userDto); - return responseHandler.handleResult(result); + return responseHandler.handle201Result(result); } @Override @GetMapping("/{username}") public ResponseEntity getUser(@PathVariable String username) { Result result = this.userService.getUser(username); - return responseHandler.handleResult(result, HttpStatus.NOT_FOUND); + return responseHandler.handle200Result(result, HttpStatus.NOT_FOUND); } @Override @@ -56,7 +56,7 @@ public ResponseEntity> getUsers(Pageable pageable) { public ResponseEntity updateUser(@PathVariable String username, @Valid @RequestBody UserDto userDto) { Result result = userService.updateUser(username, userDto); - return responseHandler.handleResult(result, HttpStatus.NOT_FOUND); + return responseHandler.handle200Result(result, HttpStatus.NOT_FOUND); } @Override @@ -64,7 +64,7 @@ public ResponseEntity updateUser(@PathVariable String username, @PreAuthorize("hasRole('ADMIN')") public ResponseEntity deleteUser(@PathVariable Integer id) { Result result = userService.deleteUser(id); - return responseHandler.handleResult(result, HttpStatus.NOT_FOUND); + return responseHandler.handle200Result(result, HttpStatus.NOT_FOUND); } } diff --git a/library-api-users-service/src/test/java/dev/earlspilner/users/rest/controller/UserRestControllerTests.java b/library-api-users-service/src/test/java/dev/earlspilner/users/rest/controller/UserRestControllerTests.java new file mode 100644 index 0000000..b5a9795 --- /dev/null +++ b/library-api-users-service/src/test/java/dev/earlspilner/users/rest/controller/UserRestControllerTests.java @@ -0,0 +1,149 @@ +package dev.earlspilner.users.rest.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import dev.earlspilner.users.mapper.UserMapper; +import dev.earlspilner.users.model.User; +import dev.earlspilner.users.model.UserRole; +import dev.earlspilner.users.service.ApplicationTestConfig; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import java.util.List; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * @author Alexander Dudkin + */ +@SpringBootTest +@ContextConfiguration(classes = ApplicationTestConfig.class) +@WebAppConfiguration +class UserRestControllerTests { + + @Autowired + private UserMapper userMapper; + + @Autowired + private UserRestController userRestController; + + private MockMvc mockMvc; + + @BeforeEach + void init() { + this.mockMvc = MockMvcBuilders.standaloneSetup(userRestController).build(); + } + + @Test + void testCreateUserSuccess() throws Exception { + User user = new User(); + user.setName("Alex Tourette"); + user.setUsername("tourette"); + user.setEmail("tourette@email.com"); + user.setPassword("password"); + user.setRoles(List.of(UserRole.ROLE_VISITOR)); + + ObjectMapper mapper = new ObjectMapper(); + String newUserAsJSON = mapper.writeValueAsString(userMapper.toUserDto(user)); + this.mockMvc.perform(post("/users") + .content(newUserAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.id").value(3)) + .andExpect(jsonPath("$.username").value("tourette")); + } + + @Test + @WithMockUser(roles = "ADMIN") + void testGetUserSuccess() throws Exception { + this.mockMvc.perform(get("/users/jbloch") + .accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isOk()); + } + + @Test + @WithMockUser(roles = "ADMIN") + void testGetUserFailure() throws Exception { + this.mockMvc.perform(get("/users/unknown") + .accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isNotFound()); + } + + @Test + @WithMockUser(roles = "ADMIN") + void testCreateUserFailureFullName() throws Exception { + User user = new User(); + user.setName(""); + user.setUsername("tourette"); + user.setEmail("tourette@email.com"); + user.setPassword("password"); + user.setRoles(List.of(UserRole.ROLE_VISITOR)); + + ObjectMapper mapper = new ObjectMapper(); + String newUserAsJSON = mapper.writeValueAsString(userMapper.toUserDto(user)); + this.mockMvc.perform(post("/users") + .content(newUserAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isBadRequest()); + } + + @Test + @WithMockUser(roles = "ADMIN") + void testCreateUserFailureUsername() throws Exception { + User user = new User(); + user.setName("Alex Tourette"); + user.setUsername(""); + user.setEmail("tourette@email.com"); + user.setPassword("password"); + user.setRoles(List.of(UserRole.ROLE_VISITOR)); + + ObjectMapper mapper = new ObjectMapper(); + String newUserAsJSON = mapper.writeValueAsString(userMapper.toUserDto(user)); + this.mockMvc.perform(post("/users") + .content(newUserAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isBadRequest()); + } + + @Test + @WithMockUser(roles = "ADMIN") + void testCreateUserFailureEmail() throws Exception { + User user = new User(); + user.setName("Alex Tourette"); + user.setUsername("tourette"); + user.setEmail(""); + user.setPassword("password"); + user.setRoles(List.of(UserRole.ROLE_VISITOR)); + + ObjectMapper mapper = new ObjectMapper(); + String newUserAsJSON = mapper.writeValueAsString(userMapper.toUserDto(user)); + this.mockMvc.perform(post("/users") + .content(newUserAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isBadRequest()); + } + + @Test + @WithMockUser(roles = "ADMIN") + void testCreateUserFailurePassword() throws Exception { + User user = new User(); + user.setName("Alex Tourette"); + user.setUsername("tourette"); + user.setEmail("tourette@email.com"); + user.setPassword(""); + user.setRoles(List.of(UserRole.ROLE_VISITOR)); + + ObjectMapper mapper = new ObjectMapper(); + String newUserAsJSON = mapper.writeValueAsString(userMapper.toUserDto(user)); + this.mockMvc.perform(post("/users") + .content(newUserAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isBadRequest()); + } + +} diff --git a/library-api-users-service/src/test/java/dev/earlspilner/users/service/ApplicationTestConfig.java b/library-api-users-service/src/test/java/dev/earlspilner/users/service/ApplicationTestConfig.java new file mode 100644 index 0000000..6505f68 --- /dev/null +++ b/library-api-users-service/src/test/java/dev/earlspilner/users/service/ApplicationTestConfig.java @@ -0,0 +1,16 @@ +package dev.earlspilner.users.service; + +import org.mockito.MockitoAnnotations; +import org.springframework.boot.test.context.TestConfiguration; + +/** + * @author Alexander Dudkin + */ +@TestConfiguration +public class ApplicationTestConfig { + + public ApplicationTestConfig() { + MockitoAnnotations.openMocks(this); + } + +} diff --git a/library-api-users-service/src/test/resources/application.properties b/library-api-users-service/src/test/resources/application.properties index 869a439..d4ba2b6 100644 --- a/library-api-users-service/src/test/resources/application.properties +++ b/library-api-users-service/src/test/resources/application.properties @@ -29,4 +29,9 @@ logging.level.org.springframework=INFO # those are used only for testing purpose jwt.secret.key=53A73E5F1C4E0A2D3B5F2D784E6A1B423D6F247D1F6E5C3A596D635A75327855 +# ------------------------------------------------ + +eureka.client.fetch-registry=false +eureka.client.register-with-eureka=false + # ------------------------------------------------ \ No newline at end of file