diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/WasteController.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/WasteController.java index ff28172f2623650fcb510fb0e702bcd8df6143bb..0c804cf2c54fec9c99ebb66a036f7625ade2801b 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/WasteController.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/WasteController.java @@ -4,11 +4,20 @@ import java.util.List; import lombok.AllArgsConstructor; import ntnu.idatt2016.v233.SmartMat.dto.request.WasteRequest; import ntnu.idatt2016.v233.SmartMat.entity.Waste; +import ntnu.idatt2016.v233.SmartMat.service.group.GroupService; import ntnu.idatt2016.v233.SmartMat.service.group.WasteService; import ntnu.idatt2016.v233.SmartMat.util.CategoryUtil; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; +/** + * Controller for handling requests related to waste + * @author Pedro, birk + * @version 1.1 + * @since 04.05.2023 + */ @AllArgsConstructor @RestController @RequestMapping("/api/waste") @@ -16,14 +25,23 @@ public class WasteController { private final WasteService wasteService; + private final GroupService groupService; + /** * Saves a new waste * * @param waste the waste to save + * @param authentication the authentication of the user * @return a ResponseEntity containing the saved waste if it was saved successfully, or a 400 if it wasn't + * or a 403 if the user is not associated with the group */ @PostMapping("/waste") - public ResponseEntity<Waste> createWaste(@RequestBody WasteRequest waste) { + public ResponseEntity<Waste> createWaste(@RequestBody WasteRequest waste, Authentication authentication) { + if(authentication.getAuthorities().stream().noneMatch(role -> role.getAuthority().equals("ADMIN"))){ + if(!(groupService.isUserAssociatedWithGroup(authentication.getName(), waste.groupId()))) + return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); + } + return wasteService.createWaste(waste).map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.unprocessableEntity().build()); } @@ -31,10 +49,16 @@ public class WasteController { * Gets a waste by its id * * @param wasteId the id of the waste - * @return a ResponseEntity containing the waste if it exists, or a 404 if it doesn't + * @param authentication the authentication of the user + * @return a ResponseEntity containing the waste if it exists, or a 404 if it doesn or a 403 if the user is not associated with the group */ @GetMapping("/{wasteId}") - public ResponseEntity<Waste> getWasteById(@PathVariable("wasteId") long wasteId) { + public ResponseEntity<Waste> getWasteById(@PathVariable("wasteId") long wasteId, Authentication authentication) { + if(authentication.getAuthorities().stream().noneMatch(role -> role.getAuthority().equals("ADMIN"))){ + if (!wasteService.isUserAssosiatedWithWaste(authentication.getName(), wasteId)) + return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); + } + return wasteService.getWasteById(wasteId) .map(ResponseEntity::ok) .orElseGet(() -> ResponseEntity.notFound().build()); @@ -44,10 +68,18 @@ public class WasteController { * Gets a waste by its group id * * @param groupId the id of the group - * @return a ResponseEntity containing the waste if it exists, or a 404 if it doesn't + * @param authentication the authentication of the user + * @return a ResponseEntity containing the waste if it exists, or a 404 if it doesn't or a 403 if the user is not associated with the group */ @GetMapping("/group/{groupId}") - public ResponseEntity<List<Waste>> getWasteByGroupId(@PathVariable("groupId") long groupId) { + public ResponseEntity<List<Waste>> getWasteByGroupId(@PathVariable("groupId") long groupId, + Authentication authentication) { + + if(authentication.getAuthorities().stream().noneMatch(role -> role.getAuthority().equals("ADMIN"))){ + if(!(groupService.isUserAssociatedWithGroup(authentication.getName(), groupId))) + return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); + } + return wasteService.getWasteByGroupId(groupId) .map(ResponseEntity::ok) .orElseGet(() -> ResponseEntity.notFound().build()); @@ -59,11 +91,19 @@ public class WasteController { * * @param groupId the ID of the group to search for * @param categoryNumber the number representing the category to search for + * @param authentication the authentication of the user * @return a ResponseEntity containing a list of Waste objects if successful, or a not found ResponseEntity if the data is not found + * or a 403 if the user is not associated with the group */ @GetMapping("/group/{groupId}/category/{categoryNumber}") public ResponseEntity<List<Waste>> getWasteOfCategoryByGroupId(@PathVariable("groupId") long groupId, - @PathVariable("categoryNumber") int categoryNumber){ + @PathVariable("categoryNumber") int categoryNumber, + Authentication authentication){ + if(authentication.getAuthorities().stream().noneMatch(role -> role.getAuthority().equals("ADMIN"))){ + if(!(groupService.isUserAssociatedWithGroup(authentication.getName(), groupId))) + return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); + } + return wasteService.getWasteOfCategoryByGroupId(groupId, CategoryUtil.getCategoryName(categoryNumber)).map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build()); } @@ -71,11 +111,18 @@ public class WasteController { * Retrieve information about the cake diagram for a given group ID using a GET request. * * @param groupId The ID of the group for which to retrieve the cake diagram information. + * @param authentication The authentication of the user. * @return A ResponseEntity containing an array of doubles representing the cake diagram information if found, - * or a 404 Not Found response if not found. + * or a 404 Not Found response if not found. If the user is not associated with the group, a 403 Forbidden */ @GetMapping("/statistic/cakeGraph/{groupId}") - public ResponseEntity<double[]> getInformationOfCakeGraph(@PathVariable("groupId") long groupId){ + public ResponseEntity<double[]> getInformationOfCakeGraph(@PathVariable("groupId") long groupId, + Authentication authentication){ + if(authentication.getAuthorities().stream().noneMatch(role -> role.getAuthority().equals("ADMIN"))){ + if(!(groupService.isUserAssociatedWithGroup(authentication.getName(), groupId))) + return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); + } + return wasteService.getCakeDiagram(groupId).map(ResponseEntity::ok).orElseGet(()->ResponseEntity.notFound().build()); } @@ -100,7 +147,11 @@ public class WasteController { * @return a ResponseEntity with the lost money as a Double if found, or a ResponseEntity with status 404 if the group is not found */ @GetMapping("/statistic/lostMoney/{groupId}") - public ResponseEntity<Double> getLostMoney(@PathVariable("groupId") long groupId){ + public ResponseEntity<Double> getLostMoney(@PathVariable("groupId") long groupId, Authentication authentication){ + if(authentication.getAuthorities().stream().noneMatch(role -> role.getAuthority().equals("ADMIN"))){ + if(!(groupService.isUserAssociatedWithGroup(authentication.getName(), groupId))) + return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); + } return wasteService.getLostMoney(groupId).map(ResponseEntity::ok).orElseGet(()->ResponseEntity.notFound().build()); } @@ -112,7 +163,12 @@ public class WasteController { * or a ResponseEntity with HTTP status 404 (not found) if the group or data is not found */ @GetMapping("/statistic/annuallyCO2/{groupId}") - public ResponseEntity<Double> getCO2Annually(@PathVariable("groupId") long groupId){ + public ResponseEntity<Double> getCO2Annually(@PathVariable("groupId") long groupId, Authentication authentication){ + if(authentication.getAuthorities().stream().noneMatch(role -> role.getAuthority().equals("ADMIN"))){ + if(!(groupService.isUserAssociatedWithGroup(authentication.getName(), groupId))) + return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); + } return wasteService.getCO2PerPerson(groupId).map(ResponseEntity::ok).orElseGet(()->ResponseEntity.notFound().build()); } + } diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/WasteService.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/WasteService.java index dffcfd8e60fe99dc0ee5dbd1747405992dd77318..3272f026f1921a22e53f2a727492346abe2a8713 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/WasteService.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/WasteService.java @@ -18,6 +18,12 @@ import org.springframework.stereotype.Service; import java.util.Optional; +/** + * Service for waste + * @author Pedro, Birk + * @version 1.1 + * @since 04.05.2023 + */ @Service @AllArgsConstructor public class WasteService { @@ -26,6 +32,11 @@ public class WasteService { private final ProductRepository productRepository; + /** + * Creates a new waste + * @param wasteRequest the waste to create + * @return an optional containing the waste if it was created + */ public Optional<Waste> createWaste(WasteRequest wasteRequest) { Optional<Group> group = groupRepository.findByGroupId(wasteRequest.groupId()); Optional<Product> product = productRepository.findById(wasteRequest.ean()); @@ -117,4 +128,16 @@ public class WasteService { return Optional.of(StatisticUtil.getAnnualAverage(wastes,number)); } + + /** + * Checks if the user is assosiated with the waste their trying to retrive + * @param username the username of the user + * @param wasteId the id of the waste + * @return true if the user is associated with the waste, false otherwise + */ + public boolean isUserAssosiatedWithWaste(String username, long wasteId) { + Optional<Waste> waste = wasteRepository.findById(wasteId); + return waste.map(value -> value.getGroupId().getUser().stream() + .anyMatch(user -> user.getUser().getUsername().equals(username))).orElse(false); + } } diff --git a/src/test/java/ntnu/idatt2016/v233/SmartMat/controller/group/WasteControllerTest.java b/src/test/java/ntnu/idatt2016/v233/SmartMat/controller/group/WasteControllerTest.java index ecfd1d94343190ba72264cf33a8c8f424668611e..c500c8cb95ace90bdcceb03835b2a2fc47751148 100644 --- a/src/test/java/ntnu/idatt2016/v233/SmartMat/controller/group/WasteControllerTest.java +++ b/src/test/java/ntnu/idatt2016/v233/SmartMat/controller/group/WasteControllerTest.java @@ -6,57 +6,152 @@ import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import java.sql.Timestamp; +import java.util.*; + +import ntnu.idatt2016.v233.SmartMat.dto.enums.Authority; +import ntnu.idatt2016.v233.SmartMat.entity.group.UserGroupAsso; +import ntnu.idatt2016.v233.SmartMat.entity.group.UserGroupId; +import ntnu.idatt2016.v233.SmartMat.entity.user.User; +import ntnu.idatt2016.v233.SmartMat.service.group.GroupService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.test.web.servlet.MockMvc; + import com.fasterxml.jackson.databind.ObjectMapper; + import ntnu.idatt2016.v233.SmartMat.dto.request.WasteRequest; -import ntnu.idatt2016.v233.SmartMat.entity.group.Group; -import ntnu.idatt2016.v233.SmartMat.entity.product.Product; import ntnu.idatt2016.v233.SmartMat.entity.Waste; import ntnu.idatt2016.v233.SmartMat.entity.group.Group; import ntnu.idatt2016.v233.SmartMat.entity.product.Product; import ntnu.idatt2016.v233.SmartMat.service.group.WasteService; import ntnu.idatt2016.v233.SmartMat.util.CategoryUtil; -import org.aspectj.lang.annotation.Before; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.test.web.servlet.MockMvc; -import java.sql.Timestamp; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -@ExtendWith(SpringExtension.class) -@WebMvcTest(WasteController.class) -@AutoConfigureMockMvc(addFilters = false) public class WasteControllerTest { - @Autowired - private MockMvc mockMvc; + @Mock + private WasteService wasteService; - @Autowired - private ObjectMapper objectMapper; + @Mock + private GroupService groupService; - @MockBean - private WasteService wasteService; + private final Authentication regularUser = new Authentication() { + @Override + public Collection<? extends GrantedAuthority> getAuthorities() { + return List.of(new SimpleGrantedAuthority(Authority.USER.name())); + } + @Override + public Object getCredentials() { + return null; + } + + @Override + public Object getDetails() { + return null; + } + + @Override + public Object getPrincipal() { + return null; + } + + @Override + public boolean isAuthenticated() { + return true; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + + } + + @Override + public String getName() { + return "regularUser"; + } + }; + + private final Authentication adminUser = new Authentication() { + @Override + public Collection<? extends GrantedAuthority> getAuthorities() { + return List.of(new SimpleGrantedAuthority(Authority.ADMIN.name())); + } + + @Override + public Object getCredentials() { + return null; + } + + @Override + public Object getDetails() { + return null; + } + + @Override + public Object getPrincipal() { + return null; + } + + @Override + public boolean isAuthenticated() { + return true; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + + } + + @Override + public String getName() { + return "test"; + } + }; + + private WasteController wasteController; + private ObjectMapper objectMapper; private Group group; private Product product; private WasteRequest wasteRequest; private Waste expectedWaste; + private User user; + @BeforeEach public void setUp() { + MockitoAnnotations.openMocks(this); + + wasteController = new WasteController(wasteService, groupService); + objectMapper = new ObjectMapper(); + group = new Group(); group.setGroupId(1L); group.setGroupName("TestGroup"); + user = User.builder() + .username("regularUser") + .password("test") + .build(); + + UserGroupAsso userGroupAsso = UserGroupAsso.builder() + .user(user) + .group(group) + .id(new UserGroupId(user.getUsername(), group.getGroupId())) + .build(); + + group.addUser(userGroupAsso); + user.addGroup(userGroupAsso); + product = new Product(); product.setEan(12345678L); @@ -69,64 +164,320 @@ public class WasteControllerTest { expectedWaste.setTimestamp(new Timestamp(System.currentTimeMillis())); expectedWaste.setAmount(0.5); expectedWaste.setUnit("kg"); + } - // Test cases go here - @Test - public void testCreateWaste() throws Exception { - when(wasteService.createWaste(wasteRequest)).thenReturn(Optional.of(expectedWaste)); + @Nested + class createWaste{ + @Test + void asAdmin() { + when(wasteService.createWaste(eq(wasteRequest))).thenReturn(Optional.of(expectedWaste)); + + ResponseEntity<Waste> result = wasteController.createWaste(wasteRequest, adminUser); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertNotNull(result.getBody()); + + assertEquals(expectedWaste.getWasteId(), result.getBody().getWasteId()); + verify(wasteService, times(1)).createWaste(eq(wasteRequest)); + } + + @Test + void asRegUser() { + when(wasteService.createWaste(eq(wasteRequest))).thenReturn(Optional.of(expectedWaste)); + when(groupService.isUserAssociatedWithGroup(eq(regularUser.getName()), eq(group.getGroupId()))) + .thenReturn(true); - mockMvc.perform(post("/api/waste/waste") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(wasteRequest))) - .andExpect(status().isOk()) - .andExpect(jsonPath("wasteId").value(expectedWaste.getWasteId())); + ResponseEntity<Waste> result = wasteController.createWaste(wasteRequest, regularUser); - verify(wasteService, times(1)).createWaste(wasteRequest); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertNotNull(result.getBody()); + + assertEquals(expectedWaste.getWasteId(), result.getBody().getWasteId()); + verify(wasteService, times(1)).createWaste(eq(wasteRequest)); + } + + @Test + void notAuthorized(){ + when(groupService.isUserAssociatedWithGroup(eq(regularUser.getName()), eq(group.getGroupId()))) + .thenReturn(false); + + ResponseEntity<Waste> result = wasteController.createWaste(wasteRequest, regularUser); + + + assertEquals(HttpStatus.FORBIDDEN, result.getStatusCode()); + assertNull(result.getBody()); + + verify(wasteService, times(0)).createWaste(eq(wasteRequest)); + } } - @Test - public void testGetWasteOfCategoryByGroupId() throws Exception { - int categoryNumber = 1; - String categoryName = CategoryUtil.getCategoryName(categoryNumber); - List<Waste> expectedWastes = Arrays.asList(new Waste(/*...*/), new Waste(/*...*/)); + @Nested + class getByCategoryAndGroup{ + @Test + void testGetWasteOfCategoryByGroupId() { + int categoryNumber = 1; + String categoryName = CategoryUtil.getCategoryName(categoryNumber); + List<Waste> expectedWastes = Arrays.asList(new Waste(/*...*/), new Waste(/*...*/)); + + when(wasteService.getWasteOfCategoryByGroupId(eq(group.getGroupId()), eq(categoryName))) + .thenReturn(Optional.of(expectedWastes)); + + ResponseEntity<List<Waste>> result = wasteController.getWasteOfCategoryByGroupId(group.getGroupId(), categoryNumber, adminUser); - when(wasteService.getWasteOfCategoryByGroupId(group.getGroupId(), categoryName)).thenReturn(Optional.of(expectedWastes)); - mockMvc.perform(get("/api/waste/group/{groupId}/category/{categoryNumber}", group.getGroupId(), categoryNumber)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", hasSize(2))) - .andExpect(jsonPath("$[0].wasteId").value(expectedWastes.get(0).getWasteId())) - .andExpect(jsonPath("$[1].wasteId").value(expectedWastes.get(1).getWasteId())); + assertEquals(HttpStatus.OK, result.getStatusCode()); - verify(wasteService, times(1)).getWasteOfCategoryByGroupId(group.getGroupId(), categoryName); + assertNotNull(result.getBody()); + assertEquals(expectedWastes, result.getBody()); + verify(wasteService, times(1)).getWasteOfCategoryByGroupId(eq(group.getGroupId()), eq(categoryName)); + } + + @Test + public void testGetWasteOfCategoryByGroupIdAsRegularUser() { + int categoryNumber = 1; + String categoryName = CategoryUtil.getCategoryName(categoryNumber); + List<Waste> expectedWastes = Arrays.asList(new Waste(/*...*/), new Waste(/*...*/)); + + when(wasteService.getWasteOfCategoryByGroupId(eq(group.getGroupId()), eq(categoryName))) + .thenReturn(Optional.of(expectedWastes)); + + when(groupService.isUserAssociatedWithGroup(eq(regularUser.getName()), eq(group.getGroupId()))) + .thenReturn(true); + + ResponseEntity<List<Waste>> result = wasteController.getWasteOfCategoryByGroupId(group.getGroupId(), categoryNumber, regularUser); + + + assertNotNull(result.getBody()); + assertEquals(expectedWastes, result.getBody()); + verify(wasteService, times(1)).getWasteOfCategoryByGroupId(eq(group.getGroupId()), eq(categoryName)); + } + + @Test + void notAuthorized(){ + int categoryNumber = 1; + String categoryName = CategoryUtil.getCategoryName(categoryNumber); + List<Waste> expectedWastes = Arrays.asList(new Waste(/*...*/), new Waste(/*...*/)); + + + when(groupService.isUserAssociatedWithGroup(eq(regularUser.getName()), eq(group.getGroupId()))) + .thenReturn(false); + + ResponseEntity<List<Waste>> result = wasteController.getWasteOfCategoryByGroupId(group.getGroupId(), categoryNumber, regularUser); + + + assertNull(result.getBody()); + verify(wasteService, times(0)).getWasteOfCategoryByGroupId(eq(group.getGroupId()), eq(categoryName)); + } } - @Test - public void testGetInformationOfCakeGraph() throws Exception { - double[] expectedData = new double[]{0.3, 0.2, 0.5}; - when(wasteService.getCakeDiagram(group.getGroupId())).thenReturn(Optional.of(expectedData)); - mockMvc.perform(get("/api/waste/statistic/cakeGraph/{groupId}", group.getGroupId())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", hasSize(3))) - .andExpect(jsonPath("$[0]").value(expectedData[0])) - .andExpect(jsonPath("$[1]").value(expectedData[1])) - .andExpect(jsonPath("$[2]").value(expectedData[2])); - verify(wasteService, times(1)).getCakeDiagram(group.getGroupId()); + @Nested + class testGetByGroupId{ + @Test + void getAsAdmin() { + List<Waste> expectedWastes = Arrays.asList(new Waste(/*...*/), new Waste(/*...*/)); + + when(wasteService.getWasteByGroupId(eq(group.getGroupId()))) + .thenReturn(Optional.of(expectedWastes)); + + ResponseEntity<List<Waste>> result = wasteController.getWasteByGroupId(group.getGroupId(), adminUser); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + + assertNotNull(result.getBody()); + + assertEquals(expectedWastes, result.getBody()); + + verify(wasteService, times(1)).getWasteByGroupId(eq(group.getGroupId())); + + } + + @Test + void getAsRegUser() { + List<Waste> expectedWastes = Arrays.asList(new Waste(/*...*/), new Waste(/*...*/)); + + when(wasteService.getWasteByGroupId(eq(group.getGroupId()))) + .thenReturn(Optional.of(expectedWastes)); + + when(groupService.isUserAssociatedWithGroup(eq(regularUser.getName()), eq(group.getGroupId()))) + .thenReturn(true); + + ResponseEntity<List<Waste>> result = wasteController.getWasteByGroupId(group.getGroupId(), regularUser); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + + assertNotNull(result.getBody()); + + assertEquals(expectedWastes, result.getBody()); + + verify(wasteService, times(1)).getWasteByGroupId(eq(group.getGroupId())); + + } + + @Test + void notAuthorized(){ + + when(groupService.isUserAssociatedWithGroup(eq(regularUser.getName()), eq(group.getGroupId()))) + .thenReturn(false); + + ResponseEntity<List<Waste>> result = wasteController.getWasteByGroupId(group.getGroupId(), regularUser); + + assertEquals(HttpStatus.FORBIDDEN, result.getStatusCode()); + + assertNull(result.getBody()); + + verify(wasteService, times(0)).getWasteByGroupId(eq(group.getGroupId())); + } + } + + + @Nested + class testGetByWasteId{ + @Test + void asAdmin() { + when(wasteService.getWasteById(eq(expectedWaste.getWasteId()))) + .thenReturn(Optional.of(expectedWaste)); + + ResponseEntity<Waste> result = wasteController.getWasteById(expectedWaste.getWasteId(), adminUser); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + + assertNotNull(result.getBody()); + + assertEquals(expectedWaste, result.getBody()); + + verify(wasteService, times(1)).getWasteById(eq(expectedWaste.getWasteId())); + } + + @Test + void asRegUser(){ + when(wasteService.getWasteById(eq(expectedWaste.getWasteId()))) + .thenReturn(Optional.of(expectedWaste)); + + when(wasteService.isUserAssosiatedWithWaste(eq(regularUser.getName()), eq(expectedWaste.getWasteId()))) + .thenReturn(true); + + ResponseEntity<Waste> result = wasteController.getWasteById(expectedWaste.getWasteId(), regularUser); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + + assertNotNull(result.getBody()); + + assertEquals(expectedWaste, result.getBody()); + + verify(wasteService, times(1)).getWasteById(eq(expectedWaste.getWasteId())); + } + + @Test + void notFound(){ + when(wasteService.getWasteById(eq(expectedWaste.getWasteId()))) + .thenReturn(Optional.empty()); + + ResponseEntity<Waste> result = wasteController.getWasteById(expectedWaste.getWasteId(), adminUser); + + assertEquals(HttpStatus.NOT_FOUND, result.getStatusCode()); + + assertNull(result.getBody()); + + verify(wasteService, times(1)).getWasteById(eq(expectedWaste.getWasteId())); + } + + @Test + void notAuthorized(){ + + when(wasteService.isUserAssosiatedWithWaste(eq(regularUser.getName()), eq(expectedWaste.getWasteId()))) + .thenReturn(false); + + ResponseEntity<Waste> result = wasteController.getWasteById(expectedWaste.getWasteId(), regularUser); + + assertEquals(HttpStatus.FORBIDDEN, result.getStatusCode()); + + assertNull(result.getBody()); + + verify(wasteService, times(0)).getWasteById(eq(expectedWaste.getWasteId())); + } } - @Test - public void testGetWasteById_NotFound() throws Exception { - long nonExistingWasteId = 99L; + @Nested + class getInformationOfCakeGraph{ + + @Test + void asAdmin() { + List<Waste> expectedWastes = Arrays.asList(new Waste(/*...*/), new Waste(/*...*/)); + + + when(wasteService.getCakeDiagram(group.getGroupId())).thenReturn(Optional.of(new double[]{1, 2, 3})); + + ResponseEntity<double[]> result = wasteController.getInformationOfCakeGraph(group.getGroupId(), adminUser); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + + assertNotNull(result.getBody()); + + assertTrue(result.getBody().length > 0); + + verify(wasteService, times(1)).getCakeDiagram(eq(group.getGroupId())); + } + + @Test + void asRegularUser() { + List<Waste> expectedWastes = Arrays.asList(new Waste(/*...*/), new Waste(/*...*/)); + + + when(wasteService.getCakeDiagram(group.getGroupId())).thenReturn(Optional.of(new double[]{1, 2, 3})); + when(groupService.isUserAssociatedWithGroup(eq(regularUser.getName()), eq(group.getGroupId()))) + .thenReturn(true); + + ResponseEntity<double[]> result = wasteController.getInformationOfCakeGraph(group.getGroupId(), regularUser); - when(wasteService.getWasteById(nonExistingWasteId)).thenReturn(Optional.empty()); - mockMvc.perform(get("/api/waste/{wasteId}", nonExistingWasteId)) - .andExpect(status().isNotFound()); + assertEquals(HttpStatus.OK, result.getStatusCode()); + + assertNotNull(result.getBody()); + + assertTrue(result.getBody().length > 0); + + verify(wasteService, times(1)).getCakeDiagram(eq(group.getGroupId())); + } + + @Test + void notFound() { + List<Waste> expectedWastes = Arrays.asList(new Waste(/*...*/), new Waste(/*...*/)); + + + when(wasteService.getCakeDiagram(group.getGroupId())).thenThrow(new NoSuchElementException()); + when(groupService.isUserAssociatedWithGroup(eq(regularUser.getName()), eq(group.getGroupId()))) + .thenReturn(true); + + assertThrows(NoSuchElementException.class, + ()-> wasteController.getInformationOfCakeGraph(group.getGroupId(), regularUser)); + + + + verify(wasteService, times(1)).getCakeDiagram(eq(group.getGroupId())); + } + + @Test + void notAuthorized() { + + + when(groupService.isUserAssociatedWithGroup(eq(regularUser.getName()), eq(group.getGroupId()))) + .thenReturn(false); + + ResponseEntity<double[]> result = wasteController + .getInformationOfCakeGraph(group.getGroupId(), regularUser); + + assertEquals(HttpStatus.FORBIDDEN, result.getStatusCode()); + + assertNull(result.getBody()); + + verify(wasteService, times(0)).getCakeDiagram(eq(group.getGroupId())); + } - verify(wasteService, times(1)).getWasteById(nonExistingWasteId); } -} + +} \ No newline at end of file