Skip to content

Commit

Permalink
test: add controller layer tests coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
thisdudkin committed Oct 10, 2024
1 parent 129ac04 commit 7a89a2b
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 6 deletions.
4 changes: 4 additions & 0 deletions library-api-users-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@
<version>5.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,17 @@
@Component
public class ResponseHandler {

public <T> ResponseEntity<?> handleResult(Result<T> result) {
public <T> ResponseEntity<?> handle201Result(Result<T> result) {
if (result instanceof Success<T> 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 <T> ResponseEntity<?> handle200Result(Result<T> result) {
if (result instanceof Success<T> success) {
return new ResponseEntity<>(success.value(), HttpStatus.OK);
} else if (result instanceof Failure<?> failure) {
Expand All @@ -23,7 +33,7 @@ public <T> ResponseEntity<?> handleResult(Result<T> result) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}

public <T> ResponseEntity<?> handleResult(Result<T> result, HttpStatus httpStatus) {
public <T> ResponseEntity<?> handle200Result(Result<T> result, HttpStatus httpStatus) {
if (result instanceof Success<T> success) {
return new ResponseEntity<>(success.value(), HttpStatus.OK);
} else if (result instanceof Failure<?> failure) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ public UserRestController(UserService userService, ResponseHandler responseHandl
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<?> addUser(@Valid @RequestBody UserDto userDto) {
Result<UserDto> result = this.userService.saveUser(userDto);
return responseHandler.handleResult(result);
return responseHandler.handle201Result(result);
}

@Override
@GetMapping("/{username}")
public ResponseEntity<?> getUser(@PathVariable String username) {
Result<UserDto> result = this.userService.getUser(username);
return responseHandler.handleResult(result, HttpStatus.NOT_FOUND);
return responseHandler.handle200Result(result, HttpStatus.NOT_FOUND);
}

@Override
Expand All @@ -56,15 +56,15 @@ public ResponseEntity<Page<?>> getUsers(Pageable pageable) {
public ResponseEntity<?> updateUser(@PathVariable String username,
@Valid @RequestBody UserDto userDto) {
Result<UserDto> result = userService.updateUser(username, userDto);
return responseHandler.handleResult(result, HttpStatus.NOT_FOUND);
return responseHandler.handle200Result(result, HttpStatus.NOT_FOUND);
}

@Override
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<?> deleteUser(@PathVariable Integer id) {
Result<Void> result = userService.deleteUser(id);
return responseHandler.handleResult(result, HttpStatus.NOT_FOUND);
return responseHandler.handle200Result(result, HttpStatus.NOT_FOUND);
}

}
Original file line number Diff line number Diff line change
@@ -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("[email protected]");
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("[email protected]");
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("[email protected]");
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("[email protected]");
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());
}

}
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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

# ------------------------------------------------

0 comments on commit 7a89a2b

Please sign in to comment.