Skip to content

Commit a25379e

Browse files
committed
feat(deleteUser): add delete user by id endpoint
1 parent 5211dd7 commit a25379e

8 files changed

Lines changed: 273 additions & 420 deletions

File tree

README.md

Lines changed: 124 additions & 396 deletions
Large diffs are not rendered by default.

src/main/java/com/xpeho/spring_boot_java_random_user/data/services/UserServiceImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,9 @@ public UserEntity save(UserEntity user) {
4242
User savedUser = userRepository.save(userConverter.toDao(user));
4343
return userConverter.toDomain(savedUser);
4444
}
45+
46+
@Override
47+
public void deleteById(long id) {
48+
userRepository.deleteById(id);
49+
}
4550
}

src/main/java/com/xpeho/spring_boot_java_random_user/domain/services/UserService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ public interface UserService {
1010
Optional<UserEntity> getById(long id);
1111

1212
UserEntity save(UserEntity user);
13+
14+
void deleteById(long id);
1315
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.xpeho.spring_boot_java_random_user.domain.usecases;
2+
3+
import com.xpeho.spring_boot_java_random_user.domain.entities.UserEntity;
4+
import com.xpeho.spring_boot_java_random_user.domain.exceptions.UserNotFoundException;
5+
import com.xpeho.spring_boot_java_random_user.domain.services.UserService;
6+
import org.springframework.stereotype.Service;
7+
8+
@Service
9+
public class DeleteUserByIdUseCase {
10+
private final UserService userService;
11+
12+
public DeleteUserByIdUseCase(UserService userService) {
13+
this.userService = userService;
14+
}
15+
16+
public void execute(long id) {
17+
userService.deleteById(id);
18+
}
19+
}

src/main/java/com/xpeho/spring_boot_java_random_user/presentation/controllers/UserController.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,7 @@
66
import com.xpeho.spring_boot_java_random_user.domain.entities.UserEntity;
77
import jakarta.validation.constraints.Max;
88
import jakarta.validation.constraints.Min;
9-
import org.springframework.web.bind.annotation.GetMapping;
10-
import org.springframework.web.bind.annotation.PathVariable;
11-
import org.springframework.web.bind.annotation.PutMapping;
12-
import org.springframework.web.bind.annotation.PostMapping;
13-
import org.springframework.web.bind.annotation.RequestBody;
14-
import org.springframework.web.bind.annotation.RequestMapping;
15-
import org.springframework.web.bind.annotation.RequestParam;
9+
import org.springframework.web.bind.annotation.*;
1610

1711

1812
import io.swagger.v3.oas.annotations.Operation;
@@ -89,4 +83,21 @@ ResponseEntity<UserEntity> updateRandomUser(
8983
@ApiResponse(responseCode = "201", description = "User successfully created")
9084
@ApiResponse(responseCode = "500", description = "Internal server error")
9185
ResponseEntity<UserEntity> createUser(@RequestBody UserRequest user);
86+
87+
88+
@DeleteMapping("/{id}")
89+
@Operation(
90+
summary = "Delete user by id",
91+
description = "Given a user by id, delete the user if it exists in the database",
92+
parameters = {
93+
@Parameter(name = "id", description = "id of the requested user")
94+
}
95+
)
96+
@ApiResponse(responseCode = "200", description = "User successfully found and returned")
97+
@ApiResponse(responseCode = "404", description = "The requested user does not exist")
98+
@ApiResponse(responseCode = "500", description = "Internal server error")
99+
void deleteUserById(
100+
@PathVariable
101+
int id
102+
);
92103
}

src/main/java/com/xpeho/spring_boot_java_random_user/presentation/handlers/UserHandler.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import com.xpeho.spring_boot_java_random_user.domain.entities.UserEntity;
44
import com.xpeho.spring_boot_java_random_user.domain.entities.UserRequest;
55
import com.xpeho.spring_boot_java_random_user.domain.exceptions.UserNotFoundException;
6-
import com.xpeho.spring_boot_java_random_user.domain.usecases.CreateUserUseCase;
7-
import com.xpeho.spring_boot_java_random_user.domain.usecases.FetchAndSaveRandomUsersUseCase;
8-
import com.xpeho.spring_boot_java_random_user.domain.usecases.GetUserByIdUseCase;
9-
import com.xpeho.spring_boot_java_random_user.domain.usecases.UpdateRandomUserUseCase;
6+
import com.xpeho.spring_boot_java_random_user.domain.usecases.*;
107
import com.xpeho.spring_boot_java_random_user.presentation.controllers.UserController;
118
import org.slf4j.Logger;
129
import org.slf4j.LoggerFactory;
@@ -29,17 +26,20 @@ public class UserHandler implements UserController {
2926
private final UpdateRandomUserUseCase updateRandomUserUseCase;
3027
private final GetUserByIdUseCase getUserByIdUseCase;
3128
private final CreateUserUseCase createUserUseCase;
29+
private final DeleteUserByIdUseCase deleteUserUseCase;
3230

3331
public UserHandler(
3432
FetchAndSaveRandomUsersUseCase fetchAndSaveRandomUsersUseCase,
3533
UpdateRandomUserUseCase updateRandomUserUseCase,
3634
GetUserByIdUseCase getUserByIdUseCase,
37-
CreateUserUseCase createUserUseCase
35+
CreateUserUseCase createUserUseCase,
36+
DeleteUserByIdUseCase deleteUserUseCase
3837
) {
3938
this.fetchAndSaveRandomUsersUseCase = fetchAndSaveRandomUsersUseCase;
4039
this.updateRandomUserUseCase = updateRandomUserUseCase;
4140
this.getUserByIdUseCase = getUserByIdUseCase;
4241
this.createUserUseCase = createUserUseCase;
42+
this.deleteUserUseCase = deleteUserUseCase;
4343

4444
}
4545

@@ -83,4 +83,13 @@ public ResponseEntity<UserEntity> createUser(@RequestBody UserRequest user) {
8383
UserEntity createdUser = createUserUseCase.execute(user);
8484
return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
8585
}
86+
87+
@Override
88+
public void deleteUserById(int id) {
89+
try {
90+
deleteUserUseCase.execute(id);
91+
} catch (UserNotFoundException e) {
92+
logger.warn("warning: the requested user does not exist : {}", e.getMessage(), e);
93+
}
94+
}
8695
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.xpeho.spring_boot_java_random_user.domain.usecases;
2+
3+
import com.xpeho.spring_boot_java_random_user.domain.services.UserService;
4+
import org.junit.jupiter.api.BeforeEach;
5+
import org.junit.jupiter.api.DisplayName;
6+
import org.junit.jupiter.api.Test;
7+
8+
import static org.mockito.Mockito.*;
9+
10+
class DeleteUserByIdUseCaseTest {
11+
private UserService userService;
12+
private DeleteUserByIdUseCase useCase;
13+
14+
@BeforeEach
15+
void setUp() {
16+
userService = mock(UserService.class);
17+
useCase = new DeleteUserByIdUseCase(userService);
18+
}
19+
20+
@Test
21+
@DisplayName("Should call userService deleteById when executing")
22+
void shouldCallDeleteByIdWhenExecuting() {
23+
long userId = 1L;
24+
25+
useCase.execute(userId);
26+
27+
verify(userService, times(1)).deleteById(userId);
28+
}
29+
30+
@Test
31+
@DisplayName("Should call userService deleteById with correct id")
32+
void shouldCallDeleteByIdWithCorrectId() {
33+
long userId = 42L;
34+
35+
useCase.execute(userId);
36+
37+
verify(userService).deleteById(42L);
38+
verifyNoMoreInteractions(userService);
39+
}
40+
41+
@Test
42+
@DisplayName("Should call userService deleteById for different ids")
43+
void shouldCallDeleteByIdForDifferentIds() {
44+
useCase.execute(1L);
45+
useCase.execute(2L);
46+
useCase.execute(3L);
47+
48+
verify(userService).deleteById(1L);
49+
verify(userService).deleteById(2L);
50+
verify(userService).deleteById(3L);
51+
verifyNoMoreInteractions(userService);
52+
}
53+
54+
@Test
55+
@DisplayName("Should not throw exception when deleting existing user")
56+
void shouldNotThrowExceptionWhenDeletingExistingUser() {
57+
long userId = 5L;
58+
doNothing().when(userService).deleteById(userId);
59+
60+
useCase.execute(userId);
61+
62+
verify(userService).deleteById(userId);
63+
}
64+
}

src/test/java/com/xpeho/spring_boot_java_random_user/presentation/UserHandlerTest.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import com.xpeho.spring_boot_java_random_user.domain.entities.UserEntity;
44
import com.xpeho.spring_boot_java_random_user.domain.entities.UserRequest;
55
import com.xpeho.spring_boot_java_random_user.domain.exceptions.UserNotFoundException;
6-
import com.xpeho.spring_boot_java_random_user.domain.usecases.CreateUserUseCase;
7-
import com.xpeho.spring_boot_java_random_user.domain.usecases.FetchAndSaveRandomUsersUseCase;
8-
import com.xpeho.spring_boot_java_random_user.domain.usecases.GetUserByIdUseCase;
9-
import com.xpeho.spring_boot_java_random_user.domain.usecases.UpdateRandomUserUseCase;
6+
import com.xpeho.spring_boot_java_random_user.domain.usecases.*;
107
import com.xpeho.spring_boot_java_random_user.presentation.handlers.UserHandler;
118
import org.junit.jupiter.api.BeforeEach;
129
import org.junit.jupiter.api.DisplayName;
@@ -17,20 +14,16 @@
1714
import java.io.IOException;
1815
import java.util.List;
1916

20-
import static org.junit.jupiter.api.Assertions.assertEquals;
21-
import static org.junit.jupiter.api.Assertions.assertNull;
22-
import static org.junit.jupiter.api.Assertions.assertTrue;
23-
import static org.mockito.Mockito.mock;
24-
import static org.mockito.Mockito.times;
25-
import static org.mockito.Mockito.verify;
26-
import static org.mockito.Mockito.when;
17+
import static org.junit.jupiter.api.Assertions.*;
18+
import static org.mockito.Mockito.*;
2719

2820
class UserHandlerTest {
2921

3022
private FetchAndSaveRandomUsersUseCase fetchAndSaveRandomUsersUseCase;
3123
private UpdateRandomUserUseCase updateRandomUserUseCase;
3224
private GetUserByIdUseCase getUserByIdUseCase;
3325
private CreateUserUseCase createUserUseCase;
26+
private DeleteUserByIdUseCase deleteUserUseCase;
3427
private UserHandler userHandler;
3528

3629
@BeforeEach
@@ -39,7 +32,8 @@ void setUp() {
3932
updateRandomUserUseCase = mock(UpdateRandomUserUseCase.class);
4033
getUserByIdUseCase = mock(GetUserByIdUseCase.class);
4134
createUserUseCase = mock(CreateUserUseCase.class);
42-
userHandler = new UserHandler(fetchAndSaveRandomUsersUseCase, updateRandomUserUseCase, getUserByIdUseCase, createUserUseCase);
35+
deleteUserUseCase = mock(DeleteUserByIdUseCase.class);
36+
userHandler = new UserHandler(fetchAndSaveRandomUsersUseCase, updateRandomUserUseCase, getUserByIdUseCase, createUserUseCase, deleteUserUseCase);
4337
}
4438

4539
@Test
@@ -134,4 +128,25 @@ void shouldReturnCreatedWhenCreateUserSucceeds() {
134128
assertEquals(created, response.getBody());
135129
verify(createUserUseCase, times(1)).execute(request);
136130
}
131+
132+
@Test
133+
@DisplayName("Should return 204 when deleteUserById succeeds")
134+
void shouldReturnNoContentWhenDeleteUserByIdSucceeds() {
135+
int userId = 42;
136+
137+
userHandler.deleteUserById(userId);
138+
139+
verify(deleteUserUseCase, times(1)).execute(userId);
140+
}
141+
142+
@Test
143+
@DisplayName("Should log warning when deleteUserById throws UserNotFoundException")
144+
void shouldLogWarningWhenDeleteUserByIdFails() {
145+
int userId = 123;
146+
doThrow(new UserNotFoundException(userId)).when(deleteUserUseCase).execute(userId);
147+
148+
userHandler.deleteUserById(userId);
149+
150+
verify(deleteUserUseCase, times(1)).execute(userId);
151+
}
137152
}

0 commit comments

Comments
 (0)