package com.ufund.api.ufundapi.service; import java.io.IOException; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; 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.Need; import com.ufund.api.ufundapi.model.Need.GoalType; import com.ufund.api.ufundapi.persistence.CupboardDAO; @Tag("Service-tier") class CupboardServiceTest { private CupboardDAO mockCupboardDAO; private CupboardService cupboardService; private AuthService mockAuthService; @BeforeEach void setupCupboardService() { mockCupboardDAO = mock(CupboardDAO.class); mockAuthService = mock(AuthService.class); cupboardService = new CupboardService(mockAuthService, mockCupboardDAO); this.mockAuthService = mock(AuthService.class); } @Test void testCreateNeed() throws IOException, DuplicateKeyException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); // 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, location, image, maxGoal, type, urgent, description); // Analyze assertNotNull(response); assertEquals(need, response); } @Test void testCreateNeedBadGoal() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = -100.0; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); // 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]); // Analyze assertThrows(IllegalArgumentException.class, () -> cupboardService.createNeed(name, location, image, maxGoal, type, urgent, description)); } @Test void testCreateNeedBadPhysicalGoal() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 1.23; GoalType type = Need.GoalType.PHYSICAL; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); // 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]); // Analyze assertThrows(IllegalArgumentException.class, () -> cupboardService.createNeed(name, location, image, maxGoal, type, urgent, description)); } @Test void testCreateNeedBadBlankFields() throws IOException { // Setup String name = ""; String location = "Atlantis"; double maxGoal = 1.23; GoalType type = Need.GoalType.PHYSICAL; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); // 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]); // Analyze assertThrows(IllegalArgumentException.class, () -> cupboardService.createNeed(name, location, image, maxGoal, type, urgent, description)); } @Test void testCreateNeedNullFields() throws IOException { // Setup String name = ""; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); // 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]); // Analyze assertThrows(IllegalArgumentException.class, () -> cupboardService.createNeed(name, location, image, maxGoal, type, urgent, description)); } @Test void testCreateNeedDuplicate() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); 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); // Analyze assertThrows(DuplicateKeyException.class, () -> cupboardService.createNeed(name, location, image, maxGoal, type, urgent, description)); } @Test void testSearchNeeds() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); 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 void testSearchNeedsFail() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); 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 void testGetNeed() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); // When the same id is passed in, our mock User DAO will return the User object when(mockCupboardDAO.getNeed(0)).thenReturn(need); // Invoke Need response = cupboardService.getNeed(need.getId()); // Analyze assertEquals(need, response); } @Test void testUpdateNeed() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); Need newNeed = new Need("Octopus", image, location, maxGoal, type, urgent, description); // 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, need.getId()); // Analyze assertEquals(newNeed, response); } @Test void testUpdateNeedBadGoal() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); // goal should not be 0, should throw error Need newNeed = new Need(name, image, location, 0, type, urgent, description); // When the same id is passed in, our mock User DAO will return the User object when(mockCupboardDAO.updateNeed(any())).thenReturn(newNeed); // Invoke and Analyze assertThrows(IllegalArgumentException.class, () -> cupboardService.updateNeed(newNeed, need.getId())); } @Test void testUpdateNeedBadPhysicalGoal() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 10; GoalType type = Need.GoalType.PHYSICAL; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); // goal should be integer, should throw error Need newNeed = new Need(name, image, location, 1.23, type, urgent, description); // When the same id is passed in, our mock User DAO will return the User object when(mockCupboardDAO.updateNeed(any())).thenReturn(newNeed); // Invoke and Analyze assertThrows(IllegalArgumentException.class, () -> cupboardService.updateNeed(newNeed, need.getId())); } @Test void testUpdateNeedBlankFields() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 10; GoalType type = Need.GoalType.PHYSICAL; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); // passed in blank name, should throw error Need newNeed = new Need("", image, location, maxGoal, type, urgent, description); // When the same id is passed in, our mock User DAO will return the User object when(mockCupboardDAO.updateNeed(any())).thenReturn(newNeed); // Invoke and Analyze assertThrows(IllegalArgumentException.class, () -> cupboardService.updateNeed(newNeed, need.getId())); } @Test void testUpdateNeedNotMatchingIDs() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 10; GoalType type = Need.GoalType.PHYSICAL; boolean urgent = false; String image = ""; String description = ""; // passed in blank name, should throw error Need newNeed = new Need(name, image, location, maxGoal, type, urgent, description); // When the same id is passed in, our mock User DAO will return the User object when(mockCupboardDAO.updateNeed(any())).thenReturn(newNeed); // Invoke and Analyze assertThrows(IllegalArgumentException.class, () -> cupboardService.updateNeed(newNeed, -1)); } @Test void testDeleteNeed() throws IOException { // Setup String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); // When the same id is passed in, our mock User DAO will return the User object when(mockCupboardDAO.deleteNeed(0)).thenReturn(true); when(mockCupboardDAO.getNeeds()).thenReturn(new Need[0]); // Invoke boolean response = cupboardService.deleteNeed(need.getId()); Need[] responseNeeds = cupboardService.getNeeds(); // Analyze assertTrue(response); assertArrayEquals(new Need[0], responseNeeds); } @Test void checkoutNeed() throws IOException, IllegalAccessException { int id = 1; String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = Need.GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); String key = "anything"; var amount = 10; doNothing().when(mockAuthService).keyIsValid(key); when(mockCupboardDAO.getNeed(id)).thenReturn(need); assertDoesNotThrow(() -> cupboardService.checkoutNeed(id, amount, key)); } @Test void checkoutNeed2() { int id = 1; String key = "anything"; var amount = -5; assertThrows(IllegalArgumentException.class, () -> cupboardService.checkoutNeed(id, amount, key)); } @Test void checkoutNeed3() throws IOException { int id = 1; String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = GoalType.PHYSICAL; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); String key = "anything"; var amount = 3.1459; when(mockCupboardDAO.getNeed(id)).thenReturn(need); assertThrows(IllegalArgumentException.class, () -> cupboardService.checkoutNeed(id, amount, key)); } @Test void checkoutNeed4() throws IOException { int id = 1; String name = "Jellyfish"; String location = "Atlantis"; double maxGoal = 100.0; GoalType type = GoalType.MONETARY; boolean urgent = false; String image = ""; String description = ""; var need = new Need(name, image, location, maxGoal, type, urgent, description); String key = "anything"; var amount = 3.1459; when(mockCupboardDAO.getNeed(id)).thenReturn(need); assertDoesNotThrow(() -> cupboardService.checkoutNeed(id, amount, key)); } }