Merge branch 'tests' into 'dev'

Tests

See merge request sa4-2020/the-sanmarinoes/backend!147
This commit is contained in:
Claudio Maggioni 2020-05-18 12:20:59 +02:00
commit 08565bbc42
8 changed files with 154 additions and 8 deletions

View file

@ -1,5 +1,5 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.models; package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
public interface BooleanTriggerable { public interface BooleanTriggerable extends Triggerable {
boolean readTriggerState(); boolean readTriggerState();
} }

View file

@ -11,6 +11,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.Transient; import javax.persistence.Transient;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
@Data @Data
@Entity @Entity
@ -47,6 +48,7 @@ public abstract class Condition<D> {
@ManyToOne @ManyToOne
@JoinColumn(name = "automation_id", updatable = false, insertable = false) @JoinColumn(name = "automation_id", updatable = false, insertable = false)
@GsonExclude @GsonExclude
@EqualsAndHashCode.Exclude
private Automation automation; private Automation automation;
@Column(name = "automation_id", nullable = false) @Column(name = "automation_id", nullable = false)

View file

@ -1,5 +1,5 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.models; package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
public interface RangeTriggerable { public interface RangeTriggerable extends Triggerable {
double readTriggerState(); double readTriggerState();
} }

View file

@ -3,10 +3,11 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude; import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import javax.persistence.*; import javax.persistence.*;
import lombok.EqualsAndHashCode;
@Entity @Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Trigger<D> { public abstract class Trigger<D extends Triggerable> {
@Transient private String kind; @Transient private String kind;
@ -41,6 +42,7 @@ public abstract class Trigger<D> {
@ManyToOne @ManyToOne
@JoinColumn(name = "automation_id", updatable = false, insertable = false) @JoinColumn(name = "automation_id", updatable = false, insertable = false)
@GsonExclude @GsonExclude
@EqualsAndHashCode.Exclude
private Automation automation; private Automation automation;
@Column(name = "automation_id", nullable = false) @Column(name = "automation_id", nullable = false)

View file

@ -0,0 +1,3 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
public interface Triggerable {}

View file

@ -8,17 +8,17 @@ import org.springframework.stereotype.Component;
@Component @Component
public class AutomationService { public class AutomationService {
private final AutomationRepository automationRepository; private final AutomationRepository automationRepository;
private final TriggerRepository<Trigger<Device>> triggerRepository; private final TriggerRepository<Trigger<?>> triggerRepository;
@Autowired @Autowired
public AutomationService( public AutomationService(
AutomationRepository automationRepository, AutomationRepository automationRepository,
TriggerRepository<Trigger<Device>> triggerRepository) { TriggerRepository<Trigger<?>> triggerRepository) {
this.automationRepository = automationRepository; this.automationRepository = automationRepository;
this.triggerRepository = triggerRepository; this.triggerRepository = triggerRepository;
} }
public List<Trigger<Device>> findTriggersByDeviceId(Long deviceId) { public List<Trigger<?>> findTriggersByDeviceId(Long deviceId) {
return triggerRepository.findAllByDeviceId(deviceId); return triggerRepository.findAllByDeviceId(deviceId);
} }

View file

@ -52,10 +52,10 @@ public class DeviceService {
if (!r.getId().equals(roomId)) throw new IllegalStateException(); if (!r.getId().equals(roomId)) throw new IllegalStateException();
} }
private void triggerTriggers(Device device, final String username) { public void triggerTriggers(Device device, final String username) {
final long deviceId = device.getId(); final long deviceId = device.getId();
final List<Trigger<Device>> triggers = automationService.findTriggersByDeviceId(deviceId); final List<Trigger<?>> triggers = automationService.findTriggersByDeviceId(deviceId);
triggers.stream() triggers.stream()
.filter(Trigger::triggered) .filter(Trigger::triggered)

View file

@ -0,0 +1,139 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.service;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
import java.util.List;
import java.util.Optional;
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;
@ExtendWith(MockitoExtension.class)
public class DeviceServiceTests {
@Mock private DeviceRepository<Device> deviceRepository;
@Mock private SceneService sceneService;
@Mock private RoomRepository roomRepository;
@Mock private AutomationService automationService;
@Mock private EagerUserRepository userRepository;
@Mock private DevicePopulationService devicePopulationService;
@Mock private DevicePropagationService devicePropagationService;
@Mock private ConditionRepository<Condition<?>> conditionRepository;
@InjectMocks private DeviceService deviceService;
@Test
public void testThrowIfRoomNotOwned() {
final Room r = new Room();
r.setId(1L);
when(roomRepository.findByIdAndUsername(1L, "user")).thenReturn(Optional.of(r));
when(roomRepository.findByIdAndUsername(2L, "user")).thenReturn(Optional.empty());
try {
deviceService.throwIfRoomNotOwned(1L, "user");
} catch (NotFoundException e) {
fail(e.getMessage());
}
assertThatThrownBy(() -> deviceService.throwIfRoomNotOwned(2L, "user"))
.isInstanceOf(NotFoundException.class);
r.setId(2L);
assertThatThrownBy(() -> deviceService.throwIfRoomNotOwned(1L, "user"))
.isInstanceOf(IllegalStateException.class);
}
@Test
public void triggerTriggers() {
final RegularLight r = new RegularLight();
r.setId(1L);
r.setOn(true);
final BooleanTrigger b = new BooleanTrigger();
b.setId(2L);
b.setDevice(r);
b.setOn(true);
b.setDeviceId(r.getId());
final BooleanCondition c = new BooleanCondition();
c.setId(3L);
c.setDevice(r);
c.setOn(true);
c.setDeviceId(r.getId());
final Scene s = new Scene();
s.setId(4L);
final Automation a = new Automation();
a.setId(5L);
final ScenePriority sp = new ScenePriority();
sp.setSceneId(s.getId());
sp.setScene(s);
sp.setAutomationId(a.getId());
sp.setAutomation(a);
a.getTriggers().add(b);
b.setAutomation(a);
b.setAutomationId(a.getId());
a.getConditions().add(c);
c.setAutomation(a);
c.setAutomationId(a.getId());
a.getScenes().add(sp);
when(automationService.findTriggersByDeviceId(1L)).thenReturn(List.of(b));
when(conditionRepository.findAllByAutomationId(5L)).thenReturn(List.of(c));
when(automationService.findByVerifiedId(5L)).thenReturn(a);
when(sceneService.findByValidatedId(4L)).thenReturn(s);
final boolean[] passed = new boolean[1];
when(sceneService.apply(s, "user", true))
.thenAnswer(
invocation -> {
passed[0] = true;
return null;
});
deviceService.triggerTriggers(r, "user");
assertThat(passed[0]).isTrue();
}
@Test
public void testSaveAsGuest() throws NotFoundException {
Thermostat t = new Thermostat();
User u = new User();
u.setUsername("user");
User host = new User();
host.setId(1L);
host.setUsername("host");
host.getGuests().add(u);
u.getHosts().add(host);
when(userRepository.findByUsername("user")).thenReturn(u);
when(userRepository.findById(1L)).thenReturn(Optional.of(host));
doNothing().when(devicePropagationService).renameIfDuplicate(t, "host");
when(deviceRepository.save(t)).thenAnswer(ta -> ta.getArguments()[0]);
assertThat(deviceService.saveAsGuest(t, "user", 1L)).isEqualTo(t);
}
}