package com.ufund.api.ufundapi.controller; import java.io.IOException; import java.security.InvalidParameterException; import java.util.Map; import static java.util.Map.entry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import com.ufund.api.ufundapi.DuplicateKeyException; import com.ufund.api.ufundapi.model.User; import com.ufund.api.ufundapi.model.UserAuth; import com.ufund.api.ufundapi.service.AuthService; import com.ufund.api.ufundapi.service.UserService; @Tag("Controller-tier") public class UserControllerTest { private UserController userController; private AuthService mockAuthService; private UserService mockUserService; private Map userMap; @BeforeEach public void setupUserController() { mockUserService = mock(UserService.class); mockAuthService = mock(AuthService.class); userController = new UserController(mockUserService, mockAuthService); userMap = Map.ofEntries( entry("username", "Test"), entry("password", "Pass") ); } @Test public void testGetUser() throws IOException { // getUser may throw IOException // Setup String username = "Test"; User user = User.create(username, "pass"); String key = UserAuth.generate(username).getKey( ); // When the same id is passed in, our mock User DAO will return the User object when(mockUserService.getUser(username)).thenReturn(user); // Invoke ResponseEntity response = userController.getUser(username, key); // Analyze assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); assertEquals(user.getUsername(), response.getBody().getUsername()); } @Test public void testGetUserNotFound() throws Exception { // createUser may throw IOException // Setup String username = "Test"; String key = UserAuth.generate(username).getKey(); // When the same id is passed in, our mock User service will return null, simulating // no User found when(mockUserService.getUser(username)).thenReturn(null); // Invoke ResponseEntity response = userController.getUser(username, key); // Analyze assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); } @Test public void testGetUserUnauthorized() throws Exception { // createUser may throw IOException // Setup String username = "Test"; String key = UserAuth.generate(username).getKey(); // When getUser is called on the Mock User service, throw an IOException // doThrow(new IllegalAccessException()).when(mockUserService).getUser(username); doThrow(new IllegalAccessException()).when(mockAuthService).authenticate(username, key); // Invoke ResponseEntity response = userController.getUser(username, key); // Analyze assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); } @Test public void testGetUserHandleException() throws Exception { // createUser may throw IOException // Setup String username = "Test"; String key = UserAuth.generate(username).getKey(); // When getUser is called on the Mock User service, throw an IOException doThrow(new IOException()).when(mockUserService).getUser(username); // Invoke ResponseEntity response = userController.getUser(username, key); // Analyze assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); } @Test public void testCreateUser() throws IOException, DuplicateKeyException { // createUser may throw IOException // Setup String username = "Test"; String password = "Pass"; User user = User.create(username, "pass"); // when createUser is called, return true simulating successful // creation and save when(mockUserService.createUser(username, password)).thenReturn(user); // Invoke ResponseEntity response = userController.createUser(userMap); // Analyze assertEquals(HttpStatus.CREATED, response.getStatusCode()); assertEquals(user, response.getBody()); } @Test public void testCreateUserFailed() throws IOException, DuplicateKeyException { // createUser may throw IOException // Setup String username = "Test"; String password = "Pass"; // when createUser is called, return false simulating failed // creation and save when(mockUserService.createUser(username, password)).thenReturn(null); // Invoke ResponseEntity response = userController.createUser(userMap); // Analyze assertEquals(HttpStatus.CONFLICT, response.getStatusCode()); } @Test public void testCreateUserDuplicate() throws IOException, DuplicateKeyException { // createUser may throw IOException // Setup String username = "Test"; String password = "Pass"; // when createUser is called, return false simulating failed // creation and save when(mockUserService.createUser(username, password)).thenThrow(DuplicateKeyException.class); // Invoke ResponseEntity response = userController.createUser(userMap); // Analyze assertEquals(HttpStatus.CONFLICT, response.getStatusCode()); } @Test public void testCreateUserHandleException() throws IOException, DuplicateKeyException { // createUser may throw IOException // Setup String username = "Test"; String password = "Pass"; // When createUser is called on the Mock User service, throw an IOException doThrow(new IOException()).when(mockUserService).createUser(username, password); // Invoke ResponseEntity response = userController.createUser(userMap); // Analyze assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); } @Test public void testUpdateUser() throws IOException { // updateUser may throw IOException // Setup String username = "Test"; User user = User.create(username, "pass"); String key = UserAuth.generate(username).getKey(); // when updateUser is called, return true simulating successful // update and save when(mockUserService.updateUser(user, username)).thenReturn(user); // Invoke ResponseEntity response = userController.updateUser(user, username, key); // Analyze assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(user, response.getBody()); } @Test public void testUpdateUserFailed() throws IOException { // updateUser may throw IOException // Setup String username = "Test"; User user = User.create(username, "pass"); String key = UserAuth.generate(username).getKey(); // when updateUser is called, return true simulating successful // update and save when(mockUserService.updateUser(user, username)).thenReturn(null); // Invoke ResponseEntity response = userController.updateUser(user, username, key); // Analyze assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); } @Test public void testUpdateUserInvalidParameter() throws IOException { // updateUser may throw IOException // Setup String username = "Test"; User user = User.create(username, "pass"); String key = UserAuth.generate(username).getKey(); // When updateUser is called on the Mock User DAO, throw an IOException doThrow(new IOException()).when(mockUserService).updateUser(user, username); // Invoke ResponseEntity response = userController.updateUser(user, username, key); // Analyze assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); } @Test public void testUpdateUserUnauthorized() throws IOException, IllegalAccessException { // updateUser may throw IOException // Setup String username = "Test"; User user = User.create(username, "pass"); String key = UserAuth.generate(username).getKey(); // When updateUser is called on the Mock User service, throw a Invalid Parameter exception // exception doThrow(new IllegalAccessException()).when(mockAuthService).authenticate(username, key); // Invoke ResponseEntity response = userController.updateUser(user, username, key); // Analyze assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); } @Test public void testDeleteUser() throws IOException { // deleteUser may throw IOException // Setup String username = "Test"; String key = UserAuth.generate(username).getKey(); // when deleteUser is called return true, simulating successful deletion when(mockUserService.deleteUser(username)).thenReturn(true); // Invoke ResponseEntity response = userController.deleteUser(username, key); // Analyze assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test public void testDeleteUserNotFound() throws IOException { // deleteUser may throw IOException // Setup String username = "Test"; String key = UserAuth.generate(username).getKey(); // when deleteUser is called return false, simulating failed deletion when(mockUserService.deleteUser(username)).thenReturn(false); // Invoke ResponseEntity response = userController.deleteUser(username, key); // Analyze assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); } @Test public void testDeleteUserHandleException() throws IOException { // deleteUser may throw IOException // Setup String username = "Test"; String key = UserAuth.generate(username).getKey(); // When deleteUser is called on the Mock User service, throw an IOException doThrow(new IOException()).when(mockUserService).deleteUser(username); // Invoke ResponseEntity response = userController.deleteUser(username, key); // Analyze assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); } @Test public void testDeleteUserUnauthorized() throws IOException, IllegalAccessException { // deleteUser may throw IOException // Setup String username = "Test"; String key = UserAuth.generate(username).getKey(); // When deleteUser is called on the Mock User service, throw an IOException doThrow(new IllegalAccessException()).when(mockAuthService).authenticate(username, key); // Invoke ResponseEntity response = userController.deleteUser(username, key); // Analyze assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); } }