diff --git a/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightControllerTests.java b/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightControllerTests.java new file mode 100644 index 0000000..8c18d81 --- /dev/null +++ b/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightControllerTests.java @@ -0,0 +1,180 @@ +package ch.usi.inf.sa4.sanmarinoes.smarthut.dimmableLightController; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; + +import ch.usi.inf.sa4.sanmarinoes.smarthut.controller.DimmableLightController; +import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.DimmableSaveRequest; +import ch.usi.inf.sa4.sanmarinoes.smarthut.error.DuplicateStateException; +import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DeviceRepository; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLight; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLightRepository; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Scene; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.SceneRepository; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.State; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.StateRepository; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.SwitchableState; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.UserRepository; +import ch.usi.inf.sa4.sanmarinoes.smarthut.service.DeviceService; +import ch.usi.inf.sa4.sanmarinoes.smarthut.utils.Utils; +import java.security.Principal; +import java.util.Optional; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +@ExtendWith(MockitoExtension.class) +@WithMockUser(username = "user") +public class DimmableLightControllerTests { + + @InjectMocks private DimmableLightController dimmableLightController; + + @Mock private DimmableLightRepository dimmableLightRepository; + + @Mock private SceneRepository sceneRepository; + + @Mock private StateRepository stateRepository; + + @Mock private DeviceService deviceService; + + @Mock private Principal mockPrincipal; + + @Mock private UserRepository userRepository; + + @Mock private DeviceRepository deviceRepository; + + @BeforeEach + public void setup() { + when(mockPrincipal.getName()).thenReturn("user"); + } + + private void checkDimmableLightAgainstRequest( + final DimmableLight toCheck, final DimmableSaveRequest request) { + assertThat(toCheck).isNotNull(); + assertThat(toCheck.getIntensity()).isEqualTo(request.getIntensity()); + assertThat(toCheck.getName()).isEqualTo(request.getName()); + assertThat(toCheck.getRoomId()).isEqualTo(request.getRoomId()); + } + + @Test + @DisplayName("when creating should return the same object") + @SneakyThrows(NotFoundException.class) + public void testCreate() { + doNothing().when(deviceService).throwIfRoomNotOwned(anyLong(), eq("user")); + when(deviceService.saveAsOwner(any(DimmableLight.class), eq("user"))) + .thenAnswer(i -> i.getArguments()[0]); + + MockHttpServletRequest request = new MockHttpServletRequest(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); + + final DimmableSaveRequest toSend = new DimmableSaveRequest(); + toSend.setName("rl"); + toSend.setRoomId(20L); + toSend.setIntensity(35); + + final DimmableLight regularLight = dimmableLightController.create(toSend, mockPrincipal); + + checkDimmableLightAgainstRequest(regularLight, toSend); + } + + @Test + @DisplayName("when updating should return the same object") + @SneakyThrows(NotFoundException.class) + public void testUpdate() { + + final DimmableSaveRequest toSend = new DimmableSaveRequest(); + toSend.setId(50L); + toSend.setName("rl"); + toSend.setRoomId(20L); + toSend.setIntensity(35); + + final DimmableLight toUpdate = new DimmableLight(); + toUpdate.setName("OOO"); + toUpdate.setRoomId(40L); + toSend.setId(50L); + toUpdate.setOn(false); + + when(dimmableLightRepository.findByIdAndUserId(anyLong(), anyLong())) + .thenReturn(java.util.Optional.of(toUpdate)); + + when(deviceService.saveAsGuest(any(DimmableLight.class), eq("user"), anyLong())) + .thenAnswer(i -> i.getArguments()[0]); + + when(Utils.returnIfGuest( + any(UserRepository.class), + any(DimmableLight.class), + anyLong(), + any(Principal.class))) + .thenAnswer(i -> i.getArguments()[1]); + + MockHttpServletRequest request = new MockHttpServletRequest(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); + + final DimmableLight dimmableLight = + dimmableLightController.update(toSend, mockPrincipal, 20L); + + checkDimmableLightAgainstRequest(dimmableLight, toSend); + } + + @Test + @DisplayName("an existing id should succeed") + @SneakyThrows(NotFoundException.class) + public void testDelete() { + + doNothing().when(deviceService).deleteByIdAsOwner(eq(42L), eq("user")); + + MockHttpServletRequest request = new MockHttpServletRequest(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); + + Assertions.assertDoesNotThrow(() -> dimmableLightController.delete(42L, mockPrincipal)); + } + + @Test + public void testSceneBinding() { + DimmableLight dimmableLight = new DimmableLight(); + when(dimmableLightRepository.findByIdAndUsername(24L, "user")) + .thenReturn(Optional.of(dimmableLight)); + Scene scene = new Scene(); + scene.setId(1L); + SwitchableState state = new SwitchableState(); + state.setSceneId(1L); + State s = dimmableLight.cloneState(); + when(sceneRepository.findById(1L)).thenReturn(Optional.of(scene)); + when(stateRepository.countByDeviceIdAndSceneId(24L, 1L)).thenReturn(0); + Assertions.assertDoesNotThrow( + () -> dimmableLightController.sceneBinding(24L, 1L, mockPrincipal)); + } + + @Test + public void testSceneBinding2() { + when(mockPrincipal.getName()).thenReturn("user"); + DimmableLight dimmableLight = new DimmableLight(); + when(dimmableLightRepository.findByIdAndUsername(24L, "user")) + .thenReturn(Optional.of(dimmableLight)); + Scene scene = new Scene(); + scene.setId(1L); + SwitchableState state = new SwitchableState(); + state.setSceneId(1L); + State s = dimmableLight.cloneState(); + when(sceneRepository.findById(1L)).thenReturn(Optional.of(scene)); + when(stateRepository.countByDeviceIdAndSceneId(24L, 1L)).thenReturn(2); + assertThatThrownBy(() -> dimmableLightController.sceneBinding(24L, 1L, mockPrincipal)) + .isInstanceOf(DuplicateStateException.class); + } +}