Merge branch 'dev' of https://lab.si.usi.ch/sa4-2020/the-sanmarinoes/backend into dev
This commit is contained in:
commit
109d2a4d44
29 changed files with 621 additions and 75 deletions
|
@ -37,6 +37,7 @@ dependencies {
|
|||
testImplementation('org.springframework.boot:spring-boot-starter-test') {
|
||||
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
|
||||
}
|
||||
testImplementation 'nl.jqno.equalsverifier:equalsverifier:3.3'
|
||||
testImplementation 'org.springframework.security:spring-security-test'
|
||||
testImplementation 'com.h2database:h2:1.4.200'
|
||||
// Fixes https://stackoverflow.com/a/60455550
|
||||
|
|
|
@ -194,6 +194,17 @@ public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@code type} identified by {@code label}. Labels are case sensitive.
|
||||
*
|
||||
* @throws IllegalArgumentException if either {@code type} or {@code label} have already been
|
||||
* registered on this type adapter.
|
||||
*/
|
||||
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type) {
|
||||
registerSubtype(type, type.getSimpleName());
|
||||
return this;
|
||||
}
|
||||
|
||||
private void initMaps(
|
||||
Gson gson,
|
||||
Map<String, TypeAdapter<?>> labelToDelegate,
|
||||
|
|
|
@ -29,7 +29,7 @@ public class ButtonDimmerController
|
|||
ButtonDimmerRepository inputRepository,
|
||||
DimmableRepository<Dimmable> outputRepository,
|
||||
DeviceService deviceService) {
|
||||
super(inputRepository, outputRepository);
|
||||
super(inputRepository, outputRepository, deviceService);
|
||||
this.deviceService = deviceService;
|
||||
this.buttonDimmerRepository = inputRepository;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import java.security.Principal;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -28,7 +27,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||
public abstract class InputDeviceConnectionController<
|
||||
I extends InputDevice & Connectable<O>, O extends OutputDevice> {
|
||||
|
||||
private class Connection {
|
||||
protected class Connection {
|
||||
private final I input;
|
||||
private final List<O> outputs;
|
||||
|
||||
|
@ -54,7 +53,7 @@ public abstract class InputDeviceConnectionController<
|
|||
return outputReposiory;
|
||||
}
|
||||
|
||||
@Autowired private DeviceService deviceService;
|
||||
private final DeviceService deviceService;
|
||||
|
||||
private final DeviceRepository<I> inputRepository;
|
||||
|
||||
|
@ -67,9 +66,12 @@ public abstract class InputDeviceConnectionController<
|
|||
* @param outputRepository the output device repository
|
||||
*/
|
||||
protected InputDeviceConnectionController(
|
||||
DeviceRepository<I> inputRepository, DeviceRepository<O> outputRepository) {
|
||||
DeviceRepository<I> inputRepository,
|
||||
DeviceRepository<O> outputRepository,
|
||||
DeviceService deviceService) {
|
||||
this.inputRepository = inputRepository;
|
||||
this.outputReposiory = outputRepository;
|
||||
this.deviceService = deviceService;
|
||||
}
|
||||
|
||||
private Connection checkConnectionIDs(Long inputId, List<Long> outputs, String username)
|
||||
|
|
|
@ -28,7 +28,7 @@ public class KnobDimmerController extends InputDeviceConnectionController<KnobDi
|
|||
KnobDimmerRepository inputRepository,
|
||||
DimmableRepository<Dimmable> outputRepository,
|
||||
DeviceService deviceService) {
|
||||
super(inputRepository, outputRepository);
|
||||
super(inputRepository, outputRepository, deviceService);
|
||||
this.knobDimmerRepository = inputRepository;
|
||||
this.deviceService = deviceService;
|
||||
}
|
||||
|
|
|
@ -64,8 +64,8 @@ public class SensorController {
|
|||
@PutMapping("/{id}/simulation")
|
||||
public Sensor updateSimulation(
|
||||
@PathVariable("id") Long sensorId,
|
||||
@RequestParam("error") BigDecimal error,
|
||||
@RequestParam("typical") BigDecimal typical,
|
||||
@RequestBody BigDecimal error,
|
||||
@RequestBody BigDecimal typical,
|
||||
final Principal principal)
|
||||
throws NotFoundException {
|
||||
return sensorService.updateSimulationFromSensor(
|
||||
|
|
|
@ -34,7 +34,7 @@ public class SwitchController extends InputDeviceConnectionController<Switch, Sw
|
|||
SwitchRepository inputRepository,
|
||||
SwitchableRepository<Switchable> outputRepository,
|
||||
DeviceService deviceService) {
|
||||
super(inputRepository, outputRepository);
|
||||
super(inputRepository, outputRepository, deviceService);
|
||||
this.deviceService = deviceService;
|
||||
this.switchRepository = inputRepository;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,6 @@ public class SensorSaveRequest {
|
|||
|
||||
@NotNull private BigDecimal value;
|
||||
|
||||
private BigDecimal error;
|
||||
|
||||
private BigDecimal typical;
|
||||
|
||||
/**
|
||||
* The room this device belongs in, as a foreign key id. To use when updating and inserting from
|
||||
* a REST call.
|
||||
|
|
|
@ -9,7 +9,7 @@ import lombok.NonNull;
|
|||
|
||||
@Data
|
||||
@Entity
|
||||
public class ConfirmationToken {
|
||||
public final class ConfirmationToken {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
|
@ -55,7 +55,6 @@ public class ConfirmationToken {
|
|||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ConfirmationToken that = (ConfirmationToken) o;
|
||||
return resetPassword == that.resetPassword
|
||||
&& Objects.equals(id, that.id)
|
||||
&& confirmToken.equals(that.confirmToken)
|
||||
&& createdDate.equals(that.createdDate)
|
||||
&& Objects.equals(user, that.user);
|
||||
|
@ -63,6 +62,6 @@ public class ConfirmationToken {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, confirmToken, createdDate, user, resetPassword);
|
||||
return Objects.hash(confirmToken, createdDate, user, resetPassword);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.HashSet;
|
|||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import javax.persistence.*;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
@ -56,6 +57,7 @@ public class User {
|
|||
@GsonExclude
|
||||
@Getter
|
||||
@ToString.Exclude
|
||||
@EqualsAndHashCode.Exclude
|
||||
private Set<User> guests = new HashSet<>();
|
||||
|
||||
@ManyToMany(cascade = CascadeType.DETACH)
|
||||
|
@ -66,6 +68,7 @@ public class User {
|
|||
@GsonExclude
|
||||
@Getter
|
||||
@ToString.Exclude
|
||||
@EqualsAndHashCode.Exclude
|
||||
private Set<User> hosts = new HashSet<>();
|
||||
|
||||
/** Determines whether a guest can access security cameras */
|
||||
|
|
|
@ -19,20 +19,33 @@ import org.springframework.stereotype.Component;
|
|||
*/
|
||||
@Component
|
||||
public class UpdateTasks {
|
||||
private final MotionSensorRepository motionSensorRepository;
|
||||
|
||||
@Autowired private SensorRepository sensorRepository;
|
||||
private final SmartPlugRepository smartPlugRepository;
|
||||
|
||||
@Autowired private MotionSensorRepository motionSensorRepository;
|
||||
private final SensorService sensorService;
|
||||
|
||||
@Autowired private SmartPlugRepository smartPlugRepository;
|
||||
private final ThermostatService thermostatService;
|
||||
|
||||
@Autowired private SensorService sensorService;
|
||||
private final MotionSensorService motionSensorService;
|
||||
|
||||
@Autowired private ThermostatService thermostatService;
|
||||
private final SensorSocketEndpoint sensorSocketEndpoint;
|
||||
|
||||
@Autowired private MotionSensorService motionSensorService;
|
||||
|
||||
@Autowired private SensorSocketEndpoint sensorSocketEndpoint;
|
||||
@Autowired
|
||||
public UpdateTasks(
|
||||
MotionSensorRepository motionSensorRepository,
|
||||
SmartPlugRepository smartPlugRepository,
|
||||
SensorService sensorService,
|
||||
ThermostatService thermostatService,
|
||||
MotionSensorService motionSensorService,
|
||||
SensorSocketEndpoint sensorSocketEndpoint) {
|
||||
this.motionSensorRepository = motionSensorRepository;
|
||||
this.smartPlugRepository = smartPlugRepository;
|
||||
this.sensorService = sensorService;
|
||||
this.thermostatService = thermostatService;
|
||||
this.motionSensorService = motionSensorService;
|
||||
this.sensorSocketEndpoint = sensorSocketEndpoint;
|
||||
}
|
||||
|
||||
/** Generates fake sensor updates every two seconds with a +/- 2.5% error */
|
||||
@Scheduled(fixedRate = 2000)
|
||||
|
@ -78,7 +91,7 @@ public class UpdateTasks {
|
|||
c.forEach(
|
||||
s ->
|
||||
sensorSocketEndpoint.queueDeviceUpdate(
|
||||
s, sensorRepository.findUser(s.getId()), false, null, false));
|
||||
s, smartPlugRepository.findUser(s.getId()), false, null, false));
|
||||
}
|
||||
|
||||
/** Sends device updates through sensor socket in batch every one second */
|
||||
|
|
|
@ -148,7 +148,7 @@ public class DevicePropagationService {
|
|||
}
|
||||
|
||||
if (causedByTrigger) {
|
||||
endpoint.queueDeviceUpdate(device, user, false, user.getId(), false);
|
||||
endpoint.queueDeviceUpdate(device, user, false, null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Sensor;
|
|||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.SensorRepository;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.socket.SensorSocketEndpoint;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Random;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -11,24 +12,39 @@ import org.springframework.stereotype.Component;
|
|||
@Component
|
||||
public class SensorService {
|
||||
|
||||
@Autowired private SensorRepository sensorRepository;
|
||||
private final SensorRepository sensorRepository;
|
||||
|
||||
@Autowired private DeviceService deviceService;
|
||||
private final DeviceService deviceService;
|
||||
|
||||
@Autowired private ThermostatService thermostatService;
|
||||
private final ThermostatService thermostatService;
|
||||
|
||||
@Autowired private SensorSocketEndpoint endpoint;
|
||||
private final SensorSocketEndpoint endpoint;
|
||||
|
||||
private Random ran = new Random();
|
||||
private final Random ran = new Random();
|
||||
|
||||
@Autowired
|
||||
public SensorService(
|
||||
SensorRepository sensorRepository,
|
||||
DeviceService deviceService,
|
||||
ThermostatService thermostatService,
|
||||
SensorSocketEndpoint endpoint) {
|
||||
this.sensorRepository = sensorRepository;
|
||||
this.deviceService = deviceService;
|
||||
this.thermostatService = thermostatService;
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
private void randomJitter(Sensor sensor) {
|
||||
BigDecimal x =
|
||||
sensor.getTypical()
|
||||
.subtract(
|
||||
sensor.getError()
|
||||
.divide(BigDecimal.valueOf(2), RoundingMode.CEILING))
|
||||
.add(
|
||||
BigDecimal.valueOf(
|
||||
ran.nextDouble() * sensor.getError().doubleValue() * 2));
|
||||
|
||||
double x;
|
||||
|
||||
x =
|
||||
(ran.nextInt(sensor.getTypical().intValue()) + sensor.getError().intValue()) * 0.975
|
||||
+ 1;
|
||||
updateValueFromSensor(sensor, BigDecimal.valueOf(x));
|
||||
updateValueFromSensor(sensor, x);
|
||||
}
|
||||
|
||||
public void sensorFakeUpdate() {
|
||||
|
|
|
@ -5,6 +5,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ThermostatRepository;
|
|||
import ch.usi.inf.sa4.sanmarinoes.smarthut.socket.SensorSocketEndpoint;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.utils.Utils;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
@ -38,12 +39,18 @@ public class ThermostatService {
|
|||
|
||||
private void randomJitter(Thermostat thermostat) {
|
||||
|
||||
double x;
|
||||
x =
|
||||
(ran.nextInt(thermostat.getTypical().intValue()) + thermostat.getErr().intValue())
|
||||
* 0.975
|
||||
+ 1;
|
||||
updateValueForThermostat(thermostat, BigDecimal.valueOf(x));
|
||||
BigDecimal x =
|
||||
thermostat
|
||||
.getTypical()
|
||||
.subtract(
|
||||
thermostat
|
||||
.getErr()
|
||||
.divide(BigDecimal.valueOf(2), RoundingMode.CEILING))
|
||||
.add(
|
||||
BigDecimal.valueOf(
|
||||
ran.nextDouble() * thermostat.getErr().doubleValue() * 2));
|
||||
|
||||
updateValueForThermostat(thermostat, x);
|
||||
}
|
||||
|
||||
private void updateValueForThermostat(Thermostat thermostat, BigDecimal value) {
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.config;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class EmailConfigurationServiceTests {
|
||||
@Test
|
||||
public void test() {
|
||||
final EmailConfigurationService s = new EmailConfigurationService();
|
||||
s.setResetPasswordSubject("s");
|
||||
s.setResetPassword("s");
|
||||
s.setResetPasswordPath("s");
|
||||
s.setResetPasswordRedirect("s");
|
||||
s.setRegistrationRedirect("s");
|
||||
assertThat(s.getResetPasswordSubject()).isEqualTo("s");
|
||||
assertThat(s.getResetPassword()).isEqualTo("s");
|
||||
assertThat(s.getResetPasswordPath()).isEqualTo("s");
|
||||
assertThat(s.getResetPasswordRedirect()).isEqualTo("s");
|
||||
assertThat(s.getRegistrationRedirect()).isEqualTo("s");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.config;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
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.security.core.userdetails.UserDetails;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
@ExtendWith({MockitoExtension.class})
|
||||
public class JWTTokenUtilsTests {
|
||||
@InjectMocks private JWTTokenUtils utils;
|
||||
|
||||
@Mock private UserDetails userDetails;
|
||||
|
||||
@Test
|
||||
public void testGenerateToken() {
|
||||
ReflectionTestUtils.setField(
|
||||
utils,
|
||||
"secret",
|
||||
"One, seven, three, four, six, seven\n"
|
||||
+ "Three, two, one, four, seven, six, charlie, three\n"
|
||||
+ "Two, seven, eight, nine, seven, seven, seven\n"
|
||||
+ "Six, four, three, tango, seven, three, two, victor, seven\n"
|
||||
+ "Three, one, one, seven, eight, eight, eight, seven, three\n"
|
||||
+ "Two, four, seven, six, seven, eight, nine\n"
|
||||
+ "Seven, six, four, three, seven, six\n"
|
||||
+ "Lock");
|
||||
when(userDetails.getUsername()).thenReturn("username");
|
||||
String token = utils.generateToken(userDetails);
|
||||
assertThat(token).isNotNull();
|
||||
assertThat(utils.validateToken(token, userDetails)).isTrue();
|
||||
assertThat(utils.getUsernameFromToken(token)).isEqualTo("username");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.config;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* <p>http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
public final class RuntimeTypeAdapterFactoryTests {
|
||||
|
||||
@Test
|
||||
public void testRuntimeTypeAdapter() {
|
||||
RuntimeTypeAdapterFactory<BillingInstrument> rta =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class)
|
||||
.registerSubtype(CreditCard.class);
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(rta).create();
|
||||
|
||||
CreditCard original = new CreditCard("Jesse", 234);
|
||||
assertEquals(
|
||||
"{\"type\":\"CreditCard\",\"cvv\":234,\"ownerName\":\"Jesse\"}",
|
||||
gson.toJson(original, BillingInstrument.class));
|
||||
BillingInstrument deserialized =
|
||||
gson.fromJson(
|
||||
"{type:'CreditCard',cvv:234,ownerName:'Jesse'}", BillingInstrument.class);
|
||||
assertEquals("Jesse", deserialized.ownerName);
|
||||
assertTrue(deserialized instanceof CreditCard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRuntimeTypeIsBaseType() {
|
||||
TypeAdapterFactory rta =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class, "type", false)
|
||||
.registerSubtype(BillingInstrument.class);
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(rta).create();
|
||||
|
||||
BillingInstrument original = new BillingInstrument("Jesse");
|
||||
assertEquals(
|
||||
"{\"type\":\"BillingInstrument\",\"ownerName\":\"Jesse\"}",
|
||||
gson.toJson(original, BillingInstrument.class));
|
||||
BillingInstrument deserialized =
|
||||
gson.fromJson(
|
||||
"{type:'BillingInstrument',ownerName:'Jesse'}", BillingInstrument.class);
|
||||
assertEquals("Jesse", deserialized.ownerName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullBaseType() {
|
||||
try {
|
||||
RuntimeTypeAdapterFactory.of(null);
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullTypeFieldName() {
|
||||
try {
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class, null);
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullSubtype() {
|
||||
RuntimeTypeAdapterFactory<BillingInstrument> rta =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class);
|
||||
try {
|
||||
rta.registerSubtype(null);
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullLabel() {
|
||||
RuntimeTypeAdapterFactory<BillingInstrument> rta =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class);
|
||||
try {
|
||||
rta.registerSubtype(CreditCard.class, null);
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateSubtype() {
|
||||
RuntimeTypeAdapterFactory<BillingInstrument> rta =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class);
|
||||
rta.registerSubtype(CreditCard.class, "CC");
|
||||
try {
|
||||
rta.registerSubtype(CreditCard.class, "Visa");
|
||||
fail();
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateLabel() {
|
||||
RuntimeTypeAdapterFactory<BillingInstrument> rta =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class);
|
||||
rta.registerSubtype(CreditCard.class, "CC");
|
||||
try {
|
||||
rta.registerSubtype(BankTransfer.class, "CC");
|
||||
fail();
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeMissingTypeField() {
|
||||
TypeAdapterFactory billingAdapter =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class)
|
||||
.registerSubtype(CreditCard.class);
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(billingAdapter).create();
|
||||
try {
|
||||
gson.fromJson("{ownerName:'Jesse'}", BillingInstrument.class);
|
||||
fail();
|
||||
} catch (JsonParseException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeMissingSubtype() {
|
||||
TypeAdapterFactory billingAdapter =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class)
|
||||
.registerSubtype(BankTransfer.class);
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(billingAdapter).create();
|
||||
try {
|
||||
gson.fromJson("{type:'CreditCard',ownerName:'Jesse'}", BillingInstrument.class);
|
||||
fail();
|
||||
} catch (JsonParseException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeMissingSubtype() {
|
||||
TypeAdapterFactory billingAdapter =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class)
|
||||
.registerSubtype(BankTransfer.class);
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(billingAdapter).create();
|
||||
try {
|
||||
gson.toJson(new CreditCard("Jesse", 456), BillingInstrument.class);
|
||||
fail();
|
||||
} catch (JsonParseException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeCollidingTypeFieldName() {
|
||||
TypeAdapterFactory billingAdapter =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class, "cvv")
|
||||
.registerSubtype(CreditCard.class);
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(billingAdapter).create();
|
||||
try {
|
||||
gson.toJson(new CreditCard("Jesse", 456), BillingInstrument.class);
|
||||
fail();
|
||||
} catch (JsonParseException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeWrappedNullValue() {
|
||||
TypeAdapterFactory billingAdapter =
|
||||
RuntimeTypeAdapterFactory.of(BillingInstrument.class)
|
||||
.registerSubtype(CreditCard.class)
|
||||
.registerSubtype(BankTransfer.class);
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(billingAdapter).create();
|
||||
String serialized =
|
||||
gson.toJson(new BillingInstrumentWrapper(null), BillingInstrumentWrapper.class);
|
||||
BillingInstrumentWrapper deserialized =
|
||||
gson.fromJson(serialized, BillingInstrumentWrapper.class);
|
||||
assertNull(deserialized.instrument);
|
||||
}
|
||||
|
||||
static class BillingInstrumentWrapper {
|
||||
BillingInstrument instrument;
|
||||
|
||||
BillingInstrumentWrapper(BillingInstrument instrument) {
|
||||
this.instrument = instrument;
|
||||
}
|
||||
}
|
||||
|
||||
static class BillingInstrument {
|
||||
private final String ownerName;
|
||||
|
||||
BillingInstrument(String ownerName) {
|
||||
this.ownerName = ownerName;
|
||||
}
|
||||
}
|
||||
|
||||
static class CreditCard extends BillingInstrument {
|
||||
int cvv;
|
||||
|
||||
CreditCard(String ownerName, int cvv) {
|
||||
super(ownerName);
|
||||
this.cvv = cvv;
|
||||
}
|
||||
}
|
||||
|
||||
static class BankTransfer extends BillingInstrument {
|
||||
int bankAccount;
|
||||
|
||||
BankTransfer(String ownerName, int bankAccount) {
|
||||
super(ownerName);
|
||||
this.bankAccount = bankAccount;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -105,7 +105,7 @@ public class DeviceControllerTests {
|
|||
public void getAllEmptyTest() {
|
||||
when(mockPrincipal.getName()).thenReturn("user");
|
||||
List<Device> l = deviceController.getAll(user.getId(), mockPrincipal);
|
||||
assertThat(l.isEmpty());
|
||||
assertThat(l.isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@DisplayName("check if list contains elements added")
|
||||
|
@ -118,7 +118,6 @@ public class DeviceControllerTests {
|
|||
Device d2 = new SmartPlug();
|
||||
deviceService.saveAsOwner(d2, mockPrincipal.getName());
|
||||
|
||||
assertThat(
|
||||
deviceController.getAll(user.getId(), mockPrincipal).containsAll(List.of(d1, d2)));
|
||||
assertThat(deviceController.getAll(user.getId(), mockPrincipal)).isNotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.mockito.ArgumentMatchers.anyIterable;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.service.DeviceService;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.security.test.context.support.WithMockUser;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@WithMockUser(username = "user")
|
||||
public class InputDeviceConnectionControllerTests {
|
||||
|
||||
@Mock private DeviceService deviceService;
|
||||
|
||||
@Mock private KnobDimmerRepository inputRepository;
|
||||
|
||||
@Mock private DimmableRepository<Dimmable> outputRepository;
|
||||
|
||||
private KnobDimmerController knobDimmerController;
|
||||
|
||||
@Mock private Principal mockPrincipal;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(mockPrincipal.getName()).thenReturn("user");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnection() throws NotFoundException {
|
||||
KnobDimmer knobDimmer = new KnobDimmer();
|
||||
DimmableLight dimmableLight = new DimmableLight();
|
||||
knobDimmer.addDimmable(dimmableLight);
|
||||
|
||||
when(inputRepository.findByIdAndUsername(anyLong(), anyString()))
|
||||
.thenReturn(java.util.Optional.of(knobDimmer));
|
||||
|
||||
when(outputRepository.findByIdAndUsername(anyLong(), anyString()))
|
||||
.thenReturn(java.util.Optional.of(dimmableLight));
|
||||
|
||||
when(deviceService.saveAllAsOwner(anyIterable(), anyString()))
|
||||
.thenReturn(List.of(new DimmableLight()));
|
||||
|
||||
List<Long> l = new ArrayList<>();
|
||||
l.add(10L);
|
||||
|
||||
knobDimmerController =
|
||||
new KnobDimmerController(inputRepository, outputRepository, deviceService);
|
||||
|
||||
assertDoesNotThrow(() -> knobDimmerController.addLight(1L, l, mockPrincipal));
|
||||
}
|
||||
}
|
|
@ -58,7 +58,7 @@ public class RegularLightControllerTests {
|
|||
@Test
|
||||
public void testGetAll() {
|
||||
when(regularLightRepository.findAll()).thenReturn(List.of());
|
||||
assertThat(regularLightController.findAll().isEmpty());
|
||||
assertThat(regularLightController.findAll()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -42,17 +42,29 @@ public class RoomControllerTests {
|
|||
|
||||
private final User u;
|
||||
|
||||
private final User h;
|
||||
|
||||
public RoomControllerTests() {
|
||||
u = new User();
|
||||
u.setName("user");
|
||||
u.setUsername("user");
|
||||
u.setId(1L);
|
||||
|
||||
h = new User();
|
||||
h.setUsername("host");
|
||||
h.setId(2L);
|
||||
u.getHosts().add(h);
|
||||
h.getGuests().add(u);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAll() throws NotFoundException {
|
||||
when(mockPrincipal.getName()).thenReturn("user");
|
||||
when(roomRepository.findByUsername("user")).thenReturn(List.of());
|
||||
when(roomRepository.findByUserId(2L)).thenReturn(List.of());
|
||||
when(userRepository.findById(2L)).thenReturn(Optional.of(h));
|
||||
when(userRepository.findByUsername("user")).thenReturn(u);
|
||||
assertThat(roomController.findAll(null, mockPrincipal)).isEmpty();
|
||||
assertThat(roomController.findAll(2L, mockPrincipal)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -67,10 +79,20 @@ public class RoomControllerTests {
|
|||
}
|
||||
|
||||
private void equalToRequest(Room created, RoomSaveRequest a) {
|
||||
assertThat(created.getName()).isEqualTo(a.getName());
|
||||
if (a.getName() != null) {
|
||||
assertThat(created.getName()).isEqualTo(a.getName());
|
||||
}
|
||||
assertThat(created.getUserId()).isEqualTo(1L);
|
||||
assertThat(created.getIcon()).isEqualTo(a.getIcon());
|
||||
assertThat(created.getImage()).isEqualTo(a.getImage());
|
||||
if (a.getIcon() != null) {
|
||||
assertThat(created.getIcon()).isEqualTo(a.getIcon());
|
||||
}
|
||||
if (a.getImage() != null) {
|
||||
if (a.getImage().isEmpty()) {
|
||||
assertThat(created.getImage()).isNull();
|
||||
} else {
|
||||
assertThat(created.getImage()).isEqualTo(a.getImage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -97,13 +119,21 @@ public class RoomControllerTests {
|
|||
when(roomRepository.findByIdAndUsername(42L, "user")).thenReturn(Optional.of(old));
|
||||
when(roomRepository.findByIdAndUsername(43L, "user")).thenReturn(Optional.empty());
|
||||
|
||||
RoomSaveRequest roomSaveRequest = new RoomSaveRequest(42L, Icon.BEER, null, "New Room");
|
||||
RoomSaveRequest roomSaveRequest = new RoomSaveRequest(42L, Icon.BEER, "image", "New Room");
|
||||
|
||||
Room created =
|
||||
roomController.update(roomSaveRequest.getId(), roomSaveRequest, mockPrincipal);
|
||||
assertThat(created.getId()).isEqualTo(42L);
|
||||
equalToRequest(created, roomSaveRequest);
|
||||
|
||||
roomSaveRequest.setImage("");
|
||||
roomSaveRequest.setIcon(null);
|
||||
roomSaveRequest.setName(null);
|
||||
|
||||
created = roomController.update(roomSaveRequest.getId(), roomSaveRequest, mockPrincipal);
|
||||
assertThat(created.getId()).isEqualTo(42L);
|
||||
equalToRequest(created, roomSaveRequest);
|
||||
|
||||
roomSaveRequest.setId(43L);
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
|
@ -119,11 +149,15 @@ public class RoomControllerTests {
|
|||
final Room toDelete = new Room();
|
||||
toDelete.setId(42L);
|
||||
|
||||
final Device d = new Thermostat();
|
||||
d.setId(2020L);
|
||||
|
||||
doNothing().when(switchRepository).deleteAllByRoomId(42L);
|
||||
doNothing().when(knobDimmerRepository).deleteAllByRoomId(42L);
|
||||
doNothing().when(buttonDimmerRepository).deleteAllByRoomId(42L);
|
||||
when(roomRepository.findByIdAndUsername(42L, "user")).thenReturn(Optional.of(toDelete));
|
||||
when(deviceService.findAll(42L, null, "user")).thenReturn(List.of());
|
||||
when(deviceService.findAll(42L, null, "user")).thenReturn(List.of(d));
|
||||
doNothing().when(deviceService).deleteByIdAsOwner(2020L, "user");
|
||||
doNothing().when(roomRepository).delete(toDelete);
|
||||
|
||||
try {
|
||||
|
@ -132,4 +166,11 @@ public class RoomControllerTests {
|
|||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDevices() throws NotFoundException {
|
||||
when(mockPrincipal.getName()).thenReturn("user");
|
||||
when(deviceService.findAll(2020L, 10L, "user")).thenReturn(List.of());
|
||||
assertThat(roomController.getDevices(2020L, mockPrincipal, 10L)).isNotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,12 +69,7 @@ public class SensorControllerTests {
|
|||
|
||||
final SensorSaveRequest toSend =
|
||||
new SensorSaveRequest(
|
||||
Sensor.SensorType.TEMPERATURE,
|
||||
BigDecimal.ZERO,
|
||||
BigDecimal.ZERO,
|
||||
BigDecimal.ZERO,
|
||||
42L,
|
||||
"Test sensor");
|
||||
Sensor.SensorType.TEMPERATURE, BigDecimal.ZERO, 42L, "Test sensor");
|
||||
final Sensor created = sensorController.create(toSend, mockPrincipal);
|
||||
|
||||
checkSensorAgainstRequest(created, toSend);
|
||||
|
|
|
@ -30,13 +30,7 @@ public class SensorSaveRequestTests {
|
|||
@DisplayName("test constructor")
|
||||
public void testConstructorNotEmpty() {
|
||||
SensorSaveRequest newSaveRequest =
|
||||
new SensorSaveRequest(
|
||||
Sensor.SensorType.HUMIDITY,
|
||||
new BigDecimal(12),
|
||||
BigDecimal.ZERO,
|
||||
BigDecimal.ZERO,
|
||||
12L,
|
||||
"name");
|
||||
new SensorSaveRequest(Sensor.SensorType.HUMIDITY, new BigDecimal(12), 12L, "name");
|
||||
assertNotNull(newSaveRequest.getSensor());
|
||||
assertNotNull(newSaveRequest.getName());
|
||||
assertNotNull(newSaveRequest.getRoomId());
|
||||
|
|
|
@ -3,6 +3,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
|||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.Date;
|
||||
import nl.jqno.equalsverifier.EqualsVerifier;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -47,7 +48,7 @@ public class ConfirmationTokenTests {
|
|||
@DisplayName("test setTimeStamp")
|
||||
public void testSetTimeStamp() {
|
||||
Date date = new Date();
|
||||
date.setTime(86400000l);
|
||||
date.setTime(86400000L);
|
||||
token.setCreatedDate(date);
|
||||
assertEquals(date, token.getCreatedDate());
|
||||
}
|
||||
|
@ -66,12 +67,27 @@ public class ConfirmationTokenTests {
|
|||
public void equals() {
|
||||
User user = new User();
|
||||
user.setName("Tizio Sempronio");
|
||||
user.setId(42l);
|
||||
user.setId(42L);
|
||||
user.setUsername("xXCoolUserNameXx");
|
||||
user.setEmail("realMail@service.ext");
|
||||
user.setPassword("alpaca");
|
||||
ConfirmationToken t = new ConfirmationToken(user);
|
||||
ConfirmationToken t = new ConfirmationToken();
|
||||
t.setUser(user);
|
||||
|
||||
assertFalse(t.equals(token));
|
||||
assertNotEquals(t, token);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsHashCode() {
|
||||
final User u = new User();
|
||||
u.setId(1L);
|
||||
final User t = new User();
|
||||
t.setId(2L);
|
||||
EqualsVerifier.forClass(ConfirmationToken.class)
|
||||
.withNonnullFields("createdDate")
|
||||
.withNonnullFields("confirmToken")
|
||||
.withPrefabValues(User.class, u, t)
|
||||
.verify();
|
||||
assertDoesNotThrow(() -> new ConfirmationToken().hashCode());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.scheduled;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.SmartPlug;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.SmartPlugRepository;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.User;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.socket.SensorSocketEndpoint;
|
||||
import java.util.List;
|
||||
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 UpdateTasksTests {
|
||||
|
||||
@InjectMocks private UpdateTasks updateTasks;
|
||||
|
||||
@Mock private SmartPlugRepository smartPlugRepository;
|
||||
|
||||
@Mock private SensorSocketEndpoint sensorSocketEndpoint;
|
||||
|
||||
@Test
|
||||
public void testSmartPlugConsumptionFakeUpdate() {
|
||||
final User u = new User();
|
||||
final SmartPlug s = new SmartPlug();
|
||||
s.setId(20L);
|
||||
doReturn(u).when(smartPlugRepository).findUser(20L);
|
||||
doNothing()
|
||||
.when(smartPlugRepository)
|
||||
.updateTotalConsumption(SmartPlug.AVERAGE_CONSUMPTION_KW);
|
||||
when(smartPlugRepository.findByOn(true)).thenReturn(List.of(s));
|
||||
doNothing().when(sensorSocketEndpoint).queueDeviceUpdate(s, u, false, null, false);
|
||||
assertDoesNotThrow(() -> updateTasks.smartPlugConsumptionFakeUpdate());
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
|
||||
|
@ -38,6 +39,6 @@ public class DevicePopulationServiceTests {
|
|||
list.add(t1);
|
||||
list.add(light2);
|
||||
doNothing().when(populationService).populateMeasuredTemperature(t1);
|
||||
service.populateComputedFields(list);
|
||||
assertDoesNotThrow(() -> service.populateComputedFields(list));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,9 +210,7 @@ public class DevicePropagationServiceTests {
|
|||
doAnswer(i -> counter[0]++)
|
||||
.when(endpoint)
|
||||
.queueDeviceUpdate(d, guest, false, host.getId(), false);
|
||||
doAnswer(i -> counter[0]++)
|
||||
.when(endpoint)
|
||||
.queueDeviceUpdate(d, host, false, host.getId(), false);
|
||||
doAnswer(i -> counter[0]++).when(endpoint).queueDeviceUpdate(d, host, false, null, false);
|
||||
|
||||
devicePropagationService.propagateUpdateAsOwner(d, "host", false);
|
||||
assertThat(counter[0]).isEqualTo(1);
|
||||
|
|
|
@ -174,7 +174,7 @@ public class DeviceServiceTests {
|
|||
currentDeviceService.saveAllAsOwner(devices, "user", true, false);
|
||||
assertThat(count[0]).isEqualTo(0);
|
||||
|
||||
currentDeviceService.saveAllAsOwner(devices, "user", false, false);
|
||||
currentDeviceService.saveAllAsOwner(devices, "user");
|
||||
assertThat(count[0]).isEqualTo(2);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.service;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Sensor;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.SensorRepository;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.User;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.socket.SensorSocketEndpoint;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.security.test.context.support.WithMockUser;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@WithMockUser(username = "user")
|
||||
public class SensorServiceTests {
|
||||
|
||||
@InjectMocks private SensorService sensorService;
|
||||
|
||||
@Mock private DeviceService deviceService;
|
||||
|
||||
@Mock private SensorSocketEndpoint endpoint;
|
||||
|
||||
@Mock private SensorRepository sensorRepository;
|
||||
|
||||
@Mock private ThermostatService thermostatService;
|
||||
|
||||
@Test
|
||||
public void testRandomJitter() {
|
||||
final Sensor s = new Sensor();
|
||||
s.setTypical(BigDecimal.ZERO);
|
||||
s.setError(BigDecimal.ONE);
|
||||
s.setId(42L);
|
||||
final User u = new User();
|
||||
u.setUsername("user");
|
||||
doNothing().when(thermostatService).updateStates();
|
||||
when(deviceService.saveAsOwner(s, "user")).thenReturn(s);
|
||||
when(sensorRepository.findUser(42L)).thenReturn(u);
|
||||
when(sensorRepository.findAll()).thenReturn(List.of(s));
|
||||
doNothing().when(endpoint).queueDeviceUpdate(s, u, false, null, false);
|
||||
assertDoesNotThrow(() -> sensorService.sensorFakeUpdate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimulation() {
|
||||
final SensorService se = Mockito.spy(sensorService);
|
||||
final Sensor s = new Sensor();
|
||||
s.setError(BigDecimal.ONE);
|
||||
s.setTypical(BigDecimal.ZERO);
|
||||
doReturn(s).when(se).update(s);
|
||||
se.updateSimulationFromSensor(s, null, null);
|
||||
assertThat(s.getError()).isEqualTo(BigDecimal.ONE);
|
||||
assertThat(s.getTypical()).isEqualTo(BigDecimal.ZERO);
|
||||
|
||||
se.updateSimulationFromSensor(s, BigDecimal.ZERO, BigDecimal.ONE);
|
||||
assertThat(s.getError()).isEqualTo(BigDecimal.ZERO);
|
||||
assertThat(s.getTypical()).isEqualTo(BigDecimal.ONE);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue