diff options
| author | Gunther6070 <haydenhartman10@yahoo.com> | 2025-03-17 17:10:38 -0400 | 
|---|---|---|
| committer | Gunther6070 <haydenhartman10@yahoo.com> | 2025-03-17 17:10:38 -0400 | 
| commit | c4316368ccd2e724de838fa6648ff390d4f417a6 (patch) | |
| tree | da20406da93c33f1fab350802cbdf5be5131560e | |
| parent | b998a4e7ca580f19ab10862de61d7458031027f2 (diff) | |
| parent | ed3d0e5e5f9c58c3926ea55a422212f4da1c8849 (diff) | |
| download | JellySolutions-c4316368ccd2e724de838fa6648ff390d4f417a6.tar.gz JellySolutions-c4316368ccd2e724de838fa6648ff390d4f417a6.tar.bz2 JellySolutions-c4316368ccd2e724de838fa6648ff390d4f417a6.zip  | |
Merge branch 'main' of https://github.com/RIT-SWEN-261-02/team-project-2245-swen-261-02-2b
Diffstat (limited to '')
15 files changed, 689 insertions, 87 deletions
diff --git a/ufund-api/data/userAuths.json b/ufund-api/data/userAuths.json index 41ff472..fea8a6f 100644 --- a/ufund-api/data/userAuths.json +++ b/ufund-api/data/userAuths.json @@ -1 +1 @@ -[{"key":"a07ae51f-f80b-4001-95f1-48c11d4917a4","username":"phil","expiration":"2025-04-05T15:04:30.900359001"},{"key":"e14f8ee5-5780-4b9b-bf34-7a41c2bbfcb4","username":"phil","expiration":"2025-04-05T13:46:10.90733016"},{"key":"d7cef571-0f76-49fe-941f-ecbeae69557a","username":"phil","expiration":"2025-04-05T15:14:00.363201102"},{"key":"eeea7b02-7265-4a26-96de-a8ad1860c533","username":"phil","expiration":"2025-03-31T23:04:47.455490668"}]
\ No newline at end of file +[{"key":"e48872fa-b89f-494a-b681-11a809d32ff4","username":"phil","expiration":"2025-04-14T17:20:23.265745224"},{"key":"31fcbc15-9902-41d2-8d6f-5b0e40ebddd2","username":"phil","expiration":"2025-04-14T16:45:41.082560826"},{"key":"3fdd4e7e-bc59-4e3a-ba5c-177d0833022a","username":"sowgro","expiration":"2025-04-14T18:35:26.42935739"},{"key":"13d12a6d-6825-4c1d-8b22-ba960de140b8","username":"phil","expiration":"2025-04-14T17:20:58.531711142"},{"key":"a07ae51f-f80b-4001-95f1-48c11d4917a4","username":"phil","expiration":"2025-04-05T15:04:30.900359001"},{"key":"cc49c007-fd36-4828-b8fa-f5b85ad0676d","username":"phil","expiration":"2025-04-14T16:46:12.80566798"},{"key":"da61796e-402a-4a80-88ae-7607a37989a4","username":"phil","expiration":"2025-04-14T17:07:10.618039573"},{"key":"e14f8ee5-5780-4b9b-bf34-7a41c2bbfcb4","username":"phil","expiration":"2025-04-05T13:46:10.90733016"},{"key":"d7cef571-0f76-49fe-941f-ecbeae69557a","username":"phil","expiration":"2025-04-05T15:14:00.363201102"},{"key":"125a4847-3a1c-4834-961f-7f96e997f92e","username":"sowgro","expiration":"2025-04-14T18:35:38.922687686"},{"key":"3fc557b6-0306-4779-9b74-b7292a5cf1cc","username":"phil","expiration":"2025-04-14T16:06:08.564069822"},{"key":"77392d17-6e0c-45ec-857d-6595a55ddd97","username":"phil","expiration":"2025-04-14T16:06:48.335542315"},{"key":"eeea7b02-7265-4a26-96de-a8ad1860c533","username":"phil","expiration":"2025-03-31T23:04:47.455490668"},{"key":"e121c7c6-e534-4fde-8a78-4f175e9db9c8","username":"phil","expiration":"2025-04-14T17:23:23.218442063"},{"key":"af38add5-b100-4b96-9ffb-5afaccd59979","username":"adf","expiration":"2025-04-14T18:18:47.670506361"},{"key":"2aeaab28-99c9-4b45-bdef-82096c70945e","username":"phil","expiration":"2025-04-14T17:19:48.552121268"},{"key":"58e4e2a2-3a36-4fd6-8bb1-ad0831664d01","username":"phil","expiration":"2025-04-12T23:17:42.638952959"},{"key":"4df8bb43-f597-49ca-863a-6e0da5280d79","username":"phil","expiration":"2025-04-14T01:13:53.799331844"},{"key":"ad6d92d4-c496-407c-823a-edaa386e67ed","username":"phil","expiration":"2025-04-14T17:07:36.032623002"},{"key":"718be1e2-cfc7-44a6-b3c6-965684d1d0a9","username":"adf","expiration":"2025-04-14T18:35:58.888847176"},{"key":"85319427-4603-4a16-af33-2e9525dda8c0","username":"phil","expiration":"2025-04-14T00:39:34.952183453"},{"key":"f5f53053-ef5e-4850-93a0-3dc20646f78b","username":"sowgro","expiration":"2025-04-14T18:11:29.438554549"},{"key":"efc531fb-ab24-4d5a-a2f5-7f4ede74819f","username":"phil","expiration":"2025-04-13T19:41:51.017327545"},{"key":"f1d6a110-4232-4ef3-b6ec-9a2962664158","username":"phil","expiration":"2025-04-14T17:23:40.834526839"}]
\ No newline at end of file diff --git a/ufund-api/data/users.json b/ufund-api/data/users.json index ae575b1..106f11e 100644 --- a/ufund-api/data/users.json +++ b/ufund-api/data/users.json @@ -1,12 +1 @@ -[ -  { -    "username": "phil", -    "passwordHash": -1054080181, -    "basket": [] -  }, -  { -    "username": "tbone", -    "passwordHash": 97526364, -    "basket": [] -  } -]
\ No newline at end of file +[{"username":"adf","passwordHash":96419,"basket":[]},{"username":"tbone","passwordHash":97526364,"basket":[]},{"username":"sowgro","passwordHash":389416948,"basket":[]},{"username":"phil","passwordHash":-1054080181,"basket":[]}]
\ No newline at end of file diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java index 1e182a6..61293b9 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java @@ -7,40 +7,35 @@ import com.fasterxml.jackson.annotation.JsonProperty;  public class User { -    @JsonProperty("username") -    private final String username; -    @JsonProperty("passwordHash") -    private int passwordHash; -    @JsonProperty("basket") -    private final List<Need> basket; - -    /** -     * Create a new user -     *  -     * @param username The name of the user -     */ -    public User(String username) { -        this.username = username; -        basket = new ArrayList<>(); +    public enum UserType { +        HELPER, +        MANAGER      } +    @JsonProperty("username") private final String username; +    @JsonProperty("passwordHash") private int passwordHash; +    @JsonProperty("basket") private final List<Need> basket; +    @JsonProperty("type") private final UserType type; +      /**       * Create a new user       *        * @param username   The name of the user       * @param basket A basket to copy from       */ -    public User(@JsonProperty("username") String username, @JsonProperty("passwordHash") int passwordHash, @JsonProperty("basket") List<Need> basket) { +    public User(@JsonProperty("username") String username, @JsonProperty("passwordHash") int passwordHash, @JsonProperty("basket") List<Need> basket, @JsonProperty("type") UserType userType) {          this.username = username;          this.basket = basket;          this.passwordHash = passwordHash; +        this.type = userType;      }      public static User create(String username, String password) {          return new User(                  username,                  password.hashCode(), -                new ArrayList<>() +                new ArrayList<>(), +                UserType.HELPER          );      } @@ -65,7 +60,11 @@ public class User {      }      public User withoutPasswordHash() { -        return new User(this.username, 0, this.basket); +        return new User(this.username, 0, this.basket, this.type); +    } + +    public UserType getType() { +        return type;      }  } diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardFileDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardFileDAO.java index c4aaca3..521acae 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardFileDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardFileDAO.java @@ -22,7 +22,7 @@ public class CupboardFileDAO implements CupboardDAO {          this.filename = filename;          this.objectMapper = objectMapper;          needs = new TreeMap<>(); -        load();  // load the heroes from the file +        load();      }      private synchronized static int nextId() { diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/service/AuthService.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/service/AuthService.java index 591d891..5a1a492 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/service/AuthService.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/service/AuthService.java @@ -1,5 +1,6 @@  package com.ufund.api.ufundapi.service; +import com.ufund.api.ufundapi.model.User;  import com.ufund.api.ufundapi.model.UserAuth;  import com.ufund.api.ufundapi.persistence.UserAuthDAO;  import org.springframework.stereotype.Component; @@ -20,13 +21,19 @@ public class AuthService {      /**       * Check if the provided key has access to the provided user.       * -     * @param username The username of the user trying to be accessed. +     * @param targetUsername The targetUsername of the user trying to be accessed.       * @param key The api key obtained by the client from logging in.       * @throws IllegalAccessException Thrown if access was denied to the user.       */ -    public void authenticate(String username, String key) throws IllegalAccessException, IOException { +    public void authenticate(String targetUsername, String key) throws IllegalAccessException, IOException {          var userAuth = userAuthDAO.getUserAuth(key); -        if (userAuth == null || !userAuth.getUsername().equals(username)) { +        if (userAuth == null) { +            throw new IllegalAccessException("Unauthenticated"); +        } + +        var username = userAuth.getUsername(); +        var userType = userService.getUser(username).getType(); +        if (!username.equals(targetUsername) && userType != User.UserType.MANAGER) {              throw new IllegalAccessException("Unauthorized");          }      } diff --git a/ufund-api/src/test/java/com/ufund/api/ufundapi/controller/AuthControllerTest.java b/ufund-api/src/test/java/com/ufund/api/ufundapi/controller/AuthControllerTest.java new file mode 100644 index 0000000..3d4637d --- /dev/null +++ b/ufund-api/src/test/java/com/ufund/api/ufundapi/controller/AuthControllerTest.java @@ -0,0 +1,104 @@ +package com.ufund.api.ufundapi.controller; + +import java.io.IOException; +import java.util.Map; +import static java.util.Map.entry; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.mockito.ArgumentMatchers.any; +import org.mockito.Mockito; +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 org.springframework.web.bind.annotation.RequestMapping; + +import com.ufund.api.ufundapi.service.AuthService; + +@RequestMapping("auth") +public class AuthControllerTest { + +    private AuthController authController; +    private AuthService mockAuthService; +    private Map<String, String> authMap; + +    @BeforeEach +    private void setupAuthController() { +        mockAuthService = mock(AuthService.class); +        authController = new AuthController(mockAuthService); + +        authMap = Map.ofEntries( +                entry("Bob", "123") +        ); +    } + +    @Test +    public void testLogin() throws IllegalAccessException, IOException { +        // Setup +        String key = "123"; + +        // Mock +        when(mockAuthService.login(any(), any())).thenReturn(key); + +        // Invoke +        ResponseEntity<String> response = authController.login(authMap); + +        // Analyze +        assertEquals(HttpStatus.OK, response.getStatusCode()); +        assertEquals(key, response.getBody()); +    } + +    @Test +    public void testLoginUnauthorized() throws IllegalAccessException, IOException { +        // Mock +        when(mockAuthService.login(any(), any())).thenThrow(IllegalAccessException.class); + +        // Invoke +        ResponseEntity<String> response = authController.login(authMap); + +        // Analyze +        assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); +    } + +    @Test +    public void testLoginIOException() throws IllegalAccessException, IOException { +        // Mock +        when(mockAuthService.login(any(), any())).thenThrow(IOException.class); + +        // Invoke +        ResponseEntity<String> response = authController.login(authMap); + +        // Analyze +        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); +    } + +    @Test +    public void testLogout() throws IllegalAccessException, IOException { +        // Setup +        String key = "123"; + +        // Invoke +        ResponseEntity<Object> response = authController.logout(key); + +        // Analyze +        assertEquals(HttpStatus.OK, response.getStatusCode()); +    } + +    @Test +    public void testLogoutIOException() throws IllegalAccessException, IOException { +        // Setup +        String key = "123"; + +        // Mock +        doThrow(new IOException()).when(mockAuthService).logout(key); + +        // Invoke +        ResponseEntity<Object> response = authController.logout(key); + +        // Analyze +        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); +    } +} diff --git a/ufund-api/src/test/java/com/ufund/api/ufundapi/controller/UserControllerTest.java b/ufund-api/src/test/java/com/ufund/api/ufundapi/controller/UserControllerTest.java index e2c959a..b6367ad 100644 --- a/ufund-api/src/test/java/com/ufund/api/ufundapi/controller/UserControllerTest.java +++ b/ufund-api/src/test/java/com/ufund/api/ufundapi/controller/UserControllerTest.java @@ -1,15 +1,15 @@  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.junit.jupiter.api.Assertions.assertNotNull;  import static org.mockito.Mockito.doThrow;  import static org.mockito.Mockito.mock;  import static org.mockito.Mockito.when; @@ -25,21 +25,27 @@ import com.ufund.api.ufundapi.service.UserService;  @Tag("Controller-tier")  public class UserControllerTest {      private UserController userController; +    private AuthService mockAuthService;      private UserService mockUserService; +    private Map<String, String> userMap;      @BeforeEach      public void setupUserController() {          mockUserService = mock(UserService.class); -        AuthService mockAuthService = mock(AuthService.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 = new User(username); -        String key = UserAuth.generate(username).getKey(); +        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); @@ -58,7 +64,7 @@ public class UserControllerTest {          // Setup          String username = "Test";          String key = UserAuth.generate(username).getKey(); -        // When the same id is passed in, our mock User DAO will return null, simulating +        // When the same id is passed in, our mock User service will return null, simulating          // no User found          when(mockUserService.getUser(username)).thenReturn(null); @@ -71,11 +77,27 @@ public class UserControllerTest {      }      @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<User> 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 DAO, throw an IOException +        // When getUser is called on the Mock User service, throw an IOException          doThrow(new IOException()).when(mockUserService).getUser(username);          // Invoke @@ -85,25 +107,17 @@ public class UserControllerTest {          assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());      } -    /***************************************************************** -     * The following tests will fail until all userController methods -     * are implemented. -     ****************************************************************/ -      @Test      public void testCreateUser() throws IOException, DuplicateKeyException { // createUser may throw IOException          // Setup          String username = "Test";          String password = "Pass"; -        User user = new User(username); +        User user = User.create(username, "pass");          // when createUser is called, return true simulating successful          // creation and save          when(mockUserService.createUser(username, password)).thenReturn(user); -        Map<String, String> userMap = Map.ofEntries( -                entry("username", "Test"), -                entry("password", "Pass") -        );         +                          // Invoke          ResponseEntity<User> response = userController.createUser(userMap); @@ -122,10 +136,23 @@ public class UserControllerTest {          // creation and save          when(mockUserService.createUser(username, password)).thenReturn(null); -        Map<String, String> userMap = Map.ofEntries( -                entry("username", "Test"), -                entry("password", "Pass") -        ); +         + +        // Invoke +        ResponseEntity<User> 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<User> response = userController.createUser(userMap); @@ -140,13 +167,10 @@ public class UserControllerTest {          String username = "Test";          String password = "Pass"; -        // When createUser is called on the Mock User DAO, throw an IOException +        // When createUser is called on the Mock User service, throw an IOException          doThrow(new IOException()).when(mockUserService).createUser(username, password); -        Map<String, String> userMap = Map.ofEntries( -                entry("username", "Test"), -                entry("password", "Pass") -        ); +                  // Invoke          ResponseEntity<User> response = userController.createUser(userMap); @@ -159,7 +183,7 @@ public class UserControllerTest {      public void testUpdateUser() throws IOException { // updateUser may throw IOException          // Setup          String username = "Test"; -        User user = new User("Bob"); +        User user = User.create(username, "pass");          String key = UserAuth.generate(username).getKey();          // when updateUser is called, return true simulating successful          // update and save @@ -177,7 +201,7 @@ public class UserControllerTest {      public void testUpdateUserFailed() throws IOException { // updateUser may throw IOException          // Setup          String username = "Test"; -        User user = new User("Bob"); +        User user = User.create(username, "pass");          String key = UserAuth.generate(username).getKey();          // when updateUser is called, return true simulating successful          // update and save @@ -191,10 +215,10 @@ public class UserControllerTest {      }      @Test -    public void testUpdateUserHandleException() throws IOException { // updateUser may throw IOException +    public void testUpdateUserInvalidParameter() throws IOException { // updateUser may throw IOException          // Setup          String username = "Test"; -        User user = new User("Bob"); +        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); @@ -207,6 +231,23 @@ public class UserControllerTest {      }      @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<User> 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"; @@ -241,7 +282,7 @@ public class UserControllerTest {          // Setup          String username = "Test";          String key = UserAuth.generate(username).getKey(); -        // When deleteUser is called on the Mock User DAO, throw an IOException +        // When deleteUser is called on the Mock User service, throw an IOException          doThrow(new IOException()).when(mockUserService).deleteUser(username);          // Invoke @@ -251,4 +292,19 @@ public class UserControllerTest {          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<Boolean> response = userController.deleteUser(username, key); + +        // Analyze +        assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); +    } +  } diff --git a/ufund-api/src/test/java/com/ufund/api/ufundapi/model/UserTest.java b/ufund-api/src/test/java/com/ufund/api/ufundapi/model/UserTest.java index 1725190..5e017dd 100644 --- a/ufund-api/src/test/java/com/ufund/api/ufundapi/model/UserTest.java +++ b/ufund-api/src/test/java/com/ufund/api/ufundapi/model/UserTest.java @@ -13,7 +13,7 @@ public class UserTest {          String name = "Bob"; -        User user = new User(name); +        User user = User.create(name, "pass");          assertNotNull(user); @@ -36,7 +36,7 @@ public class UserTest {          String expectedName = "Bob"; -        User user = new User(expectedName); +        User user = User.create(expectedName, "pass");          Need need = new Need("Test", 0, 100, Need.GoalType.MONETARY);          Need[] needs = { need }; @@ -51,7 +51,7 @@ public class UserTest {          String expectedName = "Bob"; -        User user = new User(expectedName); +        User user = User.create(expectedName, "pass");          Need need = new Need("Test", 0, 100, Need.GoalType.MONETARY);          Need need2 = new Need("Test2", 0, 100, Need.GoalType.MONETARY); @@ -68,7 +68,7 @@ public class UserTest {          String expectedName = "Bob"; -        User user = new User(expectedName); +        User user = User.create(expectedName, "pass");          assertFalse(user.verifyPassword(expectedName)); diff --git a/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/CupboardFileDAOTest.java b/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/CupboardFileDAOTest.java index 7888084..f786a8c 100644 --- a/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/CupboardFileDAOTest.java +++ b/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/CupboardFileDAOTest.java @@ -20,17 +20,18 @@ import com.ufund.api.ufundapi.model.Need.GoalType;  @Tag("Persistence-tier")  public class CupboardFileDAOTest { -    CupboardFileDAO cupboardFileDao; -    Need[] testNeeds; -    ObjectMapper mockObjectMapper; +    private CupboardFileDAO cupboardFileDao; +    private Need[] testNeeds; +    private ObjectMapper mockObjectMapper;      @BeforeEach      public void setupCupboardFileDao() throws IOException {          mockObjectMapper = mock(ObjectMapper.class); -        testNeeds = new Need[3]; -        testNeeds[0] = new Need("one", 0, 100, Need.GoalType.MONETARY); -		testNeeds[1] = new Need("two", 1, 100, Need.GoalType.MONETARY); -		testNeeds[2] = new Need("three", 2, 100, Need.GoalType.MONETARY); +        testNeeds = new Need[]{ +        	new Need("one", 0, 100, Need.GoalType.MONETARY), +			new Need("two", 1, 100, Need.GoalType.MONETARY), +			new Need("three", 2, 100, Need.GoalType.MONETARY) +		};          // When the object mapper is supposed to read from the file          // the mock object mapper will return the hero array above          when(mockObjectMapper diff --git a/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/UserAuthFileDAOTest.java b/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/UserAuthFileDAOTest.java new file mode 100644 index 0000000..f7db747 --- /dev/null +++ b/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/UserAuthFileDAOTest.java @@ -0,0 +1,63 @@ +package com.ufund.api.ufundapi.persistence; + +import java.io.File; +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ufund.api.ufundapi.model.UserAuth; + +@Tag("Persistence-tier") +public class UserAuthFileDAOTest { + +    private UserAuthFIleDAO userAuthFIleDAO; +    private ObjectMapper mockObjectMapper; +    private UserAuth[] userAuths; + +    @BeforeEach +    public void setupUserAuthFileDAO() throws IOException { + +        mockObjectMapper = mock(ObjectMapper.class); +        userAuths = new UserAuth[]{ +        	new UserAuth("123", "Phil", null), +            new UserAuth("456", "Bob", null), +            new UserAuth("789", "Steve", null) +		}; +        // When the object mapper is supposed to read from the file +        // the mock object mapper will return the hero array above +        when(mockObjectMapper +            .readValue(new File("doesnt_matter.txt"),UserAuth[].class)) +                .thenReturn(userAuths); +        userAuthFIleDAO = new UserAuthFIleDAO(mockObjectMapper, "doesnt_matter.txt"); +    } + +    @Test +    public void getUserAuthTest() { +        String key = "123"; +        UserAuth auth = userAuthFIleDAO.getUserAuth(key); + +        assertEquals(auth, userAuths[0]); +    } + +    @Test +    public void addUserAuthTest() throws IOException { +        UserAuth auth = new UserAuth("999", "Fish", null); + +        assertDoesNotThrow(() -> userAuthFIleDAO.addUserAuth(auth)); +    } + +    @Test +    public void removeUserAuthTest() throws IOException { +        String key = "123"; + +        assertDoesNotThrow(() -> userAuthFIleDAO.removeUserAuth(key)); +    } +     +} diff --git a/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/UserFileDAOTest.java b/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/UserFileDAOTest.java index b802669..9361188 100644 --- a/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/UserFileDAOTest.java +++ b/ufund-api/src/test/java/com/ufund/api/ufundapi/persistence/UserFileDAOTest.java @@ -27,9 +27,9 @@ public class UserFileDAOTest {      public void setupHeroFileDAO() throws IOException {          mockObjectMapper = mock(ObjectMapper.class);          testUsers = new User[3]; -        testUsers[0] = new User("bob"); -		testUsers[1] = new User("admin"); -		testUsers[2] = new User("jelly12"); +        testUsers[0] = User.create("bob", "pass"); +		testUsers[1] = User.create("admin", "pass"); +		testUsers[2] = User.create("jelly12", "pass");          // When the object mapper is supposed to read from the file          // the mock object mapper will return the hero array above @@ -75,7 +75,7 @@ public class UserFileDAOTest {  	@Test  	public void createUserTest() throws IOException { -		User newUser = new User("keshey"); +		User newUser = User.create("keshey", "pass");  		userFileDAO.addUser(newUser);  		User actualUser = userFileDAO.getUser("keshey"); diff --git a/ufund-api/src/test/java/com/ufund/api/ufundapi/service/AuthServiceTest.java b/ufund-api/src/test/java/com/ufund/api/ufundapi/service/AuthServiceTest.java new file mode 100644 index 0000000..7770c40 --- /dev/null +++ b/ufund-api/src/test/java/com/ufund/api/ufundapi/service/AuthServiceTest.java @@ -0,0 +1,110 @@ +package com.ufund.api.ufundapi.service; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +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.persistence.UserAuthDAO; + +@Tag("Service-tier") +public class AuthServiceTest { + +    private UserAuthDAO mockAuthDAO; +    private UserService mockUserService; +    private AuthService authService; +    private String username; +    private String key; +    private String password; +    private User user; + +    @BeforeEach +    public void setupAuthService() { +        mockAuthDAO = mock(UserAuthDAO.class); +        mockUserService = mock(UserService.class); +        authService = new AuthService(mockAuthDAO, mockUserService); +         +        username = "Fish"; +        password = "sticks"; +        key = UserAuth.generate(username).getKey(); +        user = User.create(username, password); + +    } + +    @Test +    public void testAuthenticate() throws IOException { +        // Mock +        when(mockAuthDAO.getUserAuth(key)).thenReturn(new UserAuth(key, username, null)); +        when(mockUserService.getUser(username)).thenReturn(user); + +        // Analyze +        assertDoesNotThrow(() -> authService.authenticate(username, key)); + +    } + +    @Test +    public void testAuthenticateMismatchName() throws IOException { +        // Mock +        when(mockAuthDAO.getUserAuth(key)).thenReturn(new UserAuth(key, "EvilFish", null)); +        when(mockUserService.getUser("EvilFish")).thenReturn(user); + +        // Analyze +        assertThrows(IllegalAccessException.class, () -> authService.authenticate(username, key)); + +    } + +    @Test +    public void testAuthenticateMissingUserAuth() throws IOException { +        // Mock +        when(mockAuthDAO.getUserAuth(key)).thenReturn(null); + +        // Analyze +        assertThrows(IllegalAccessException.class, () -> authService.authenticate(username, key)); +         +    } + +    @Test +    public void testLogin() throws IOException, DuplicateKeyException, IllegalAccessException { +        // Mock +        when(mockUserService.getUser(username)).thenReturn(user); +                 + +        // Analyze +        assertDoesNotThrow(() -> authService.login(username, password)); +    } + +    @Test +    public void testLoginNullUser() throws IOException, DuplicateKeyException, IllegalAccessException { +        // Mock +        when(mockUserService.getUser(username)).thenReturn(null); + +        // Analyze +        assertThrows(IllegalAccessException.class, () -> authService.login(username, password)); +    } + +    @Test +    public void testLoginMismatchPasswords() throws IOException, DuplicateKeyException, IllegalAccessException { +        // Mock +        when(mockUserService.getUser(username)).thenReturn(User.create(username, "fries")); + +        // Analyze +        assertThrows(IllegalAccessException.class, () -> authService.login(username, password)); +    } + +    @Test +    public void testLogout() throws IOException, DuplicateKeyException, IllegalAccessException { +        // Analyze +        assertDoesNotThrow(() -> authService.logout(key)); +         +    } +     +} diff --git a/ufund-api/src/test/java/com/ufund/api/ufundapi/service/CupboardServiceTest.java b/ufund-api/src/test/java/com/ufund/api/ufundapi/service/CupboardServiceTest.java index ceef215..99ca23c 100644 --- a/ufund-api/src/test/java/com/ufund/api/ufundapi/service/CupboardServiceTest.java +++ b/ufund-api/src/test/java/com/ufund/api/ufundapi/service/CupboardServiceTest.java @@ -2,8 +2,11 @@ package com.ufund.api.ufundapi.service;  import java.io.IOException; +import static org.junit.jupiter.api.Assertions.assertArrayEquals;  import static org.junit.jupiter.api.Assertions.assertEquals;  import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue;  import static org.mockito.Mockito.*;  import org.junit.jupiter.api.BeforeEach; @@ -19,13 +22,11 @@ import com.ufund.api.ufundapi.persistence.CupboardDAO;  public class CupboardServiceTest {      private CupboardDAO mockCupboardDAO; -    private AuthService mockAuthService;      private CupboardService cupboardService;      @BeforeEach      public void setupCupboardService() {          mockCupboardDAO = mock(CupboardDAO.class); -        mockAuthService = mock(AuthService.class);          cupboardService = new CupboardService(mockCupboardDAO);      } @@ -35,15 +36,12 @@ public class CupboardServiceTest {          // Setup          String name = "Jellyfish";          double maxGoal = 100.00; -        int id = 0;          GoalType type = GoalType.MONETARY;          Need need = new Need(name, type, maxGoal);          // When the same id is passed in, our mock User DAO will return the User object -        when(mockCupboardDAO.getNeed(id)).thenReturn(need);          when(mockCupboardDAO.addNeed(any())).thenReturn(need);          when(mockCupboardDAO.getNeeds()).thenReturn(new Need[0]); -                  // Invoke          Need response = cupboardService.createNeed(name, maxGoal, type); @@ -53,4 +51,147 @@ public class CupboardServiceTest {          assertEquals(need, response);      } -} +    @Test +    public void testCreateNeedBadGoal() throws IOException, DuplicateKeyException { +        // Setup +        String name = "Jellyfish"; +        double maxGoal = -100.00; +        GoalType type = GoalType.MONETARY; +        Need need = new Need(name, type, maxGoal); + +        // When the same id is passed in, our mock User DAO will return the User object +        when(mockCupboardDAO.addNeed(any())).thenReturn(need); +        when(mockCupboardDAO.getNeeds()).thenReturn(new Need[0]); + +        // Invoke +        // Need response = cupboardService.createNeed(name, maxGoal, type); + +        // Analyze +        assertThrows(IllegalArgumentException.class, () -> { +            cupboardService.createNeed(name, maxGoal, type); +        }); +    } + +    @Test +    public void testCreateNeedDuplicate() throws IOException, DuplicateKeyException { +        // Setup +        String name = "Jellyfish"; +        double maxGoal = 100.00; +        GoalType type = GoalType.MONETARY; +        Need need = new Need(name, type, maxGoal); +        Need[] needs = { need }; + +        // When the same id is passed in, our mock User DAO will return the User object +        when(mockCupboardDAO.addNeed(any())).thenReturn(need); +        when(mockCupboardDAO.getNeeds()).thenReturn(needs); + +        // Invoke +        // Need response = cupboardService.createNeed(name, maxGoal, type); + +        // Analyze +        assertThrows(DuplicateKeyException.class, () -> { +            cupboardService.createNeed(name, maxGoal, type); +        }); +    } + +    @Test +    public void testSearchNeeds() throws IOException, DuplicateKeyException { +        // Setup +        String name = "Jellyfish"; +        double maxGoal = 100.00; +        GoalType type = GoalType.MONETARY; +        Need need = new Need(name, type, maxGoal); +        Need[] needs = { need }; + +        // When the same id is passed in, our mock User DAO will return the User object +        when(mockCupboardDAO.getNeeds()).thenReturn(needs); + +        // Invoke +        Need[] response = cupboardService.searchNeeds("Jelly"); + +        // Analyze +        assertEquals(need, response[0]); +        assertEquals(need.getName(), response[0].getName()); +    } + +    @Test +    public void testSearchNeedsFail() throws IOException, DuplicateKeyException { +        // Setup +        String name = "Jellyfish"; +        double maxGoal = 100.00; +        GoalType type = GoalType.MONETARY; +        Need need = new Need(name, type, maxGoal); +        Need[] needs = { need }; + +        // When the same id is passed in, our mock User DAO will return the User object +        when(mockCupboardDAO.getNeeds()).thenReturn(needs); + +        // Invoke +        Need[] response = cupboardService.searchNeeds("Octopus"); + +        // Analyze +        assertArrayEquals(new Need[0], response); +    } + +    @Test +    public void testGetNeed() throws IOException, DuplicateKeyException { +        // Setup +        String name = "Jellyfish"; +        double maxGoal = 100.00; +        int id = 0; +        GoalType type = GoalType.MONETARY; +        Need need = new Need(name, type, maxGoal); + +        // When the same id is passed in, our mock User DAO will return the User object +        when(mockCupboardDAO.getNeed(id)).thenReturn(need); + +        // Invoke +        Need response = cupboardService.getNeed(id); + +        // Analyze +        assertEquals(need, response); +    } + +    @Test +    public void testUpdateNeed() throws IOException, DuplicateKeyException { +        // Setup +        String name = "Jellyfish"; +        double maxGoal = 100.00; +        int id = 0; +        GoalType type = GoalType.MONETARY; +        Need need = new Need(name, type, maxGoal); +        Need newNeed = new Need("Octopus", type, maxGoal); + +        // When the same id is passed in, our mock User DAO will return the User object +        when(mockCupboardDAO.updateNeed(any())).thenReturn(newNeed); + +        // Invoke +        Need response = cupboardService.updateNeed(newNeed, id); + +        // Analyze +        assertEquals(newNeed, response); +    } + +    @Test +    public void testDeleteNeed() throws IOException, DuplicateKeyException { +        // Setup +        String name = "Jellyfish"; +        double maxGoal = 100.00; +        int id = 0; +        GoalType type = GoalType.MONETARY; +        Need need = new Need(name, type, maxGoal); + +        // When the same id is passed in, our mock User DAO will return the User object +        when(mockCupboardDAO.deleteNeed(id)).thenReturn(true); +        when(mockCupboardDAO.getNeeds()).thenReturn(new Need[0]); + +        // Invoke +        boolean response = cupboardService.deleteNeed(id); +        Need[] responseNeeds = cupboardService.getNeeds(); + +        // Analyze +        assertTrue(response); +        assertArrayEquals(new Need[0], responseNeeds); +    } + +}
\ No newline at end of file diff --git a/ufund-api/src/test/java/com/ufund/api/ufundapi/service/UserServiceTest.java b/ufund-api/src/test/java/com/ufund/api/ufundapi/service/UserServiceTest.java new file mode 100644 index 0000000..0a0cb71 --- /dev/null +++ b/ufund-api/src/test/java/com/ufund/api/ufundapi/service/UserServiceTest.java @@ -0,0 +1,126 @@ +package com.ufund.api.ufundapi.service; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.ufund.api.ufundapi.DuplicateKeyException; +import com.ufund.api.ufundapi.model.User; +import com.ufund.api.ufundapi.persistence.UserDAO; + +public class UserServiceTest { + +    private UserService userService; +    private UserDAO mockUserDAO; + + +    @BeforeEach +    public void setupUserService() { +        mockUserDAO = mock(UserDAO.class); +        userService = new UserService(mockUserDAO); +    } + +    @Test +    public void testCreateUser() throws IOException, DuplicateKeyException { +        // Setup +        String username = "Jelly"; +        String password = "Fish"; +        User user = User.create(username, password); + +        // Mock +        when(mockUserDAO.getUser(username)).thenReturn(null); +        when(mockUserDAO.addUser(any())).thenReturn(user); + +        // Invoke + +        // Analyze +        assertEquals(user, userService.createUser(username, password)); +    } + +    @Test +    public void testCreateUserDuplicate() throws IOException, DuplicateKeyException { +        // Setup +        String username = "Jelly"; +        String password = "Fish"; +        User user = User.create(username, password); + +        // Mock +        when(mockUserDAO.getUser(username)).thenReturn(User.create("Phil", "Phil")); +        when(mockUserDAO.addUser(any())).thenReturn(user); + +        // Analyze +        assertThrows(DuplicateKeyException.class, () -> userService.createUser(username, password)); +    } + +    @Test +    public void testGetUser() throws IOException, DuplicateKeyException { +        // Setup +        String username = "Jelly"; +        String password = "Fish"; +        User user = User.create(username, password); + +        // Mock +        when(mockUserDAO.getUser(username)).thenReturn(user); + +        // Analyze +        assertEquals(user, userService.getUser(username)); +    } + +    @Test +    public void testUpdateUser() throws IOException, DuplicateKeyException { +        // Setup +        String username = "Jelly"; +        String password = "Fish"; +        User oldUser = User.create(username, password); + +        String newUsername = "Jelly"; +        String newPassword = "Dog"; +        User newUser = User.create(newUsername, newPassword); + +        // Mock +        when(mockUserDAO.updateUser(newUser)).thenReturn(newUser); + +        // Analyze +        assertEquals(newUser, userService.updateUser(newUser, oldUser.getUsername())); +    } + +    @Test +    public void testUpdateUserDifferentUsernames() throws IOException, DuplicateKeyException { +        // Setup +        String username = "Jelly"; +        String password = "Fish"; +        User oldUser = User.create(username, password); + +        String newUsername = "Cat"; +        String newPassword = "Fish"; +        User newUser = User.create(newUsername, newPassword); + +        // Mock +        when(mockUserDAO.updateUser(newUser)).thenReturn(newUser); + +        // Analyze +        assertThrows(IllegalArgumentException.class, () -> userService.updateUser(newUser, oldUser.getUsername())); +    } + +    @Test +    public void testDeleteUser() throws IOException, DuplicateKeyException { +        // Setup +        String username = "Jelly"; +        String password = "Fish"; +        User user = User.create(username, password); + +        // Mock +        when(mockUserDAO.deleteUser(username)).thenReturn(true); + +        // Analyze +        assertTrue(userService.deleteUser(username)); +    } +     +} diff --git a/ufund-ui/src/app/models/User.ts b/ufund-ui/src/app/models/User.ts index 9149fe7..141f8aa 100644 --- a/ufund-ui/src/app/models/User.ts +++ b/ufund-ui/src/app/models/User.ts @@ -1,6 +1,12 @@  import {Need} from './Need'; +enum userType { +    HELPER, +    MANAGER +} +  export interface User {    username: string;    basket: Need[]; +  type: userType  }  | 
