386 lines
13 KiB
C++
386 lines
13 KiB
C++
#include <QtTest/QtTest>
|
|
#include "sensors/sensor.h"
|
|
|
|
class TestSensor : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
private slots:
|
|
void initTestCase()
|
|
{
|
|
// Setup for all tests
|
|
}
|
|
|
|
void testSensorCreation()
|
|
{
|
|
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 0.0, "test_sensor");
|
|
|
|
QCOMPARE(sensor.type, Sensor::TYPE_TEMPERATURE);
|
|
QCOMPARE(sensor.name, QString("test_sensor"));
|
|
}
|
|
|
|
void testSensorData()
|
|
{
|
|
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 0.0, "temp_sensor");
|
|
|
|
// Test setting and getting values
|
|
sensor.field = 25.0;
|
|
QCOMPARE(sensor.field, 25.0);
|
|
}
|
|
|
|
void testSensorTypes()
|
|
{
|
|
// Test different sensor types
|
|
Sensor doorSensor(Sensor::TYPE_DOOR, 1);
|
|
Sensor tempSensor(Sensor::TYPE_TEMPERATURE, 2);
|
|
Sensor humiditySensor(Sensor::TYPE_HUMIDITY, 3);
|
|
|
|
QCOMPARE(doorSensor.type, Sensor::TYPE_DOOR);
|
|
QCOMPARE(tempSensor.type, Sensor::TYPE_TEMPERATURE);
|
|
QCOMPARE(humiditySensor.type, Sensor::TYPE_HUMIDITY);
|
|
}
|
|
|
|
void testSensorStringParsing()
|
|
{
|
|
// Test parsing sensor from string (format: "SENSOR TYPE: X ID: Y FIELD: Z TIME: T")
|
|
// This tests the sensorFromString function
|
|
QString sensorStr = "SENSOR TYPE: 1 ID: 5 FIELD: 250 TIME: 1234567890";
|
|
Sensor sensor = Sensor::sensorFromString(sensorStr);
|
|
|
|
// The function should parse the type, id, and field
|
|
// Note: temperature and humidity values are divided by 10
|
|
QVERIFY(sensor.type != Sensor::TYPE_DUMMY || sensor.field != 0);
|
|
}
|
|
|
|
void testSensorStringParsingInvalid()
|
|
{
|
|
// Test parsing invalid string returns dummy sensor
|
|
QString invalidStr = "invalid data";
|
|
Sensor sensor = Sensor::sensorFromString(invalidStr);
|
|
|
|
// Should return a dummy sensor with hidden=true
|
|
QVERIFY(sensor.hidden);
|
|
}
|
|
|
|
void testSensorToString()
|
|
{
|
|
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.5, "test_sensor");
|
|
QString str = sensor.toString();
|
|
|
|
// Should contain type, id, and field info
|
|
QVERIFY(str.contains("SENSOR TYPE"));
|
|
QVERIFY(str.contains("ID:"));
|
|
QVERIFY(str.contains("FIELD:"));
|
|
}
|
|
|
|
void testSensorJsonSerialization()
|
|
{
|
|
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0, "test_sensor");
|
|
|
|
QJsonObject json;
|
|
sensor.store(json);
|
|
|
|
// Verify JSON contents
|
|
QVERIFY(json.contains("Type"));
|
|
QVERIFY(json.contains("SensorType"));
|
|
QVERIFY(json.contains("Id"));
|
|
QVERIFY(json.contains("Field"));
|
|
QVERIFY(json.contains("Name"));
|
|
QVERIFY(json.contains("Unit"));
|
|
|
|
// Check values
|
|
QVERIFY(json["Type"].toString() == "Sensor");
|
|
QVERIFY(json["SensorType"].toInt() == Sensor::TYPE_TEMPERATURE);
|
|
QVERIFY(json["Id"].toInt() == 1);
|
|
QVERIFY(json["Field"].toDouble() == 25.0);
|
|
QVERIFY(json["Name"].toString() == "test_sensor");
|
|
}
|
|
|
|
void testSensorJsonDeserialization()
|
|
{
|
|
QJsonObject json;
|
|
json["SensorType"] = Sensor::TYPE_HUMIDITY;
|
|
json["Id"] = 5;
|
|
json["Field"] = 60.5;
|
|
json["Name"] = "humidity_sensor";
|
|
json["Hidden"] = false;
|
|
|
|
Sensor sensor(json);
|
|
|
|
QVERIFY(sensor.type == Sensor::TYPE_HUMIDITY);
|
|
QVERIFY(sensor.id == 5);
|
|
QVERIFY(sensor.field == 60.5);
|
|
QVERIFY(sensor.name == "humidity_sensor");
|
|
QVERIFY(!sensor.hidden);
|
|
}
|
|
|
|
void testSensorEquality()
|
|
{
|
|
Sensor sensor1(Sensor::TYPE_TEMPERATURE, 1, 25.0);
|
|
Sensor sensor2(Sensor::TYPE_TEMPERATURE, 1, 30.0);
|
|
Sensor sensor3(Sensor::TYPE_TEMPERATURE, 2, 25.0);
|
|
|
|
// Same type and id means equal
|
|
QVERIFY(sensor1 == sensor2);
|
|
|
|
// Different id means not equal
|
|
QVERIFY(sensor1 != sensor3);
|
|
}
|
|
|
|
void testSensorUpdateSeen()
|
|
{
|
|
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0);
|
|
QDateTime before = sensor.lastSeen;
|
|
|
|
// Wait a tiny bit and update
|
|
sensor.updateSeen();
|
|
|
|
QVERIFY(sensor.lastSeen >= before);
|
|
}
|
|
|
|
void testSensorGenerateName()
|
|
{
|
|
// Test auto-generated names for different sensor types
|
|
Sensor tempSensor(Sensor::TYPE_TEMPERATURE, 1);
|
|
QVERIFY(tempSensor.name.contains("Temperature"));
|
|
|
|
Sensor doorSensor(Sensor::TYPE_DOOR, 2);
|
|
QVERIFY(doorSensor.name.contains("Door"));
|
|
|
|
Sensor buttonSensor(Sensor::TYPE_BUTTON, 3);
|
|
QVERIFY(buttonSensor.name.contains("Button"));
|
|
|
|
Sensor humiditySensor(Sensor::TYPE_HUMIDITY, 4);
|
|
QVERIFY(humiditySensor.name.contains("Humidity"));
|
|
}
|
|
|
|
void testSensorGetUnit()
|
|
{
|
|
Sensor tempSensor(Sensor::TYPE_TEMPERATURE, 1);
|
|
QVERIFY(tempSensor.getUnit() == "°C");
|
|
|
|
Sensor humiditySensor(Sensor::TYPE_HUMIDITY, 1);
|
|
QVERIFY(humiditySensor.getUnit() == "%");
|
|
|
|
Sensor pressureSensor(Sensor::TYPE_PRESSURE, 1);
|
|
QVERIFY(pressureSensor.getUnit() == "hPa");
|
|
|
|
Sensor brightnessSensor(Sensor::TYPE_BRIGHTNESS, 1);
|
|
QVERIFY(brightnessSensor.getUnit() == "lx");
|
|
|
|
Sensor co2Sensor(Sensor::TYPE_CO2, 1);
|
|
QVERIFY(co2Sensor.getUnit() == "ppm");
|
|
|
|
Sensor vocSensor(Sensor::TYPE_TOTAL_VOC, 1);
|
|
QVERIFY(vocSensor.getUnit() == "ppb");
|
|
}
|
|
|
|
void testSensorHidden()
|
|
{
|
|
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0, "test", false);
|
|
QVERIFY(!sensor.hidden);
|
|
|
|
Sensor hiddenSensor(Sensor::TYPE_TEMPERATURE, 2, 25.0, "test", true);
|
|
QVERIFY(hiddenSensor.hidden);
|
|
}
|
|
|
|
void testSensorAllTypes()
|
|
{
|
|
// Test all sensor types can be created
|
|
Sensor door(Sensor::TYPE_DOOR, 1);
|
|
Sensor temp(Sensor::TYPE_TEMPERATURE, 1);
|
|
Sensor humidity(Sensor::TYPE_HUMIDITY, 1);
|
|
Sensor pressure(Sensor::TYPE_PRESSURE, 1);
|
|
Sensor brightness(Sensor::TYPE_BRIGHTNESS, 1);
|
|
Sensor button(Sensor::TYPE_BUTTON, 1);
|
|
Sensor adc(Sensor::TYPE_ADC, 1);
|
|
Sensor co2(Sensor::TYPE_CO2, 1);
|
|
Sensor pm25(Sensor::TYPE_PM25, 1);
|
|
Sensor voc(Sensor::TYPE_TOTAL_VOC, 1);
|
|
Sensor lowBattery(Sensor::TYPE_LOWBATTERY, 1);
|
|
Sensor occupancy(Sensor::TYPE_OCUPANCY, 1);
|
|
Sensor sunAlt(Sensor::TYPE_SUN_ALTITUDE, 1);
|
|
Sensor audio(Sensor::TYPE_AUDIO_OUTPUT, 1);
|
|
|
|
// All should be valid
|
|
QVERIFY(door.type == Sensor::TYPE_DOOR);
|
|
QVERIFY(temp.type == Sensor::TYPE_TEMPERATURE);
|
|
QVERIFY(humidity.type == Sensor::TYPE_HUMIDITY);
|
|
QVERIFY(pressure.type == Sensor::TYPE_PRESSURE);
|
|
QVERIFY(brightness.type == Sensor::TYPE_BRIGHTNESS);
|
|
QVERIFY(button.type == Sensor::TYPE_BUTTON);
|
|
QVERIFY(adc.type == Sensor::TYPE_ADC);
|
|
QVERIFY(co2.type == Sensor::TYPE_CO2);
|
|
QVERIFY(pm25.type == Sensor::TYPE_PM25);
|
|
QVERIFY(voc.type == Sensor::TYPE_TOTAL_VOC);
|
|
QVERIFY(lowBattery.type == Sensor::TYPE_LOWBATTERY);
|
|
QVERIFY(occupancy.type == Sensor::TYPE_OCUPANCY);
|
|
QVERIFY(sunAlt.type == Sensor::TYPE_SUN_ALTITUDE);
|
|
QVERIFY(audio.type == Sensor::TYPE_AUDIO_OUTPUT);
|
|
}
|
|
|
|
void testSensorStoreUserUpdateUpdatesNameAndHidden()
|
|
{
|
|
// Create a SensorStore
|
|
SensorStore store;
|
|
store.getSensors()->clear();
|
|
|
|
// Add initial sensor
|
|
Sensor initialSensor(Sensor::TYPE_TEMPERATURE, 1, 20.0, "Initial Name", false);
|
|
store.sensorGotState(initialSensor, SENSOR_UPDATE_BACKEND);
|
|
|
|
// Verify initial state
|
|
std::vector<Sensor>* sensors = store.getSensors();
|
|
QVERIFY(sensors->size() == 1);
|
|
QVERIFY(sensors->at(0).name == "Initial Name");
|
|
QVERIFY(sensors->at(0).hidden == false);
|
|
|
|
// Send USER update with new name and hidden state
|
|
Sensor userUpdate(Sensor::TYPE_TEMPERATURE, 1, 25.0, "New Name", true);
|
|
store.sensorGotState(userUpdate, SENSOR_UPDATE_USER);
|
|
|
|
// Verify name and hidden were updated, but field was NOT updated
|
|
// (USER updates only update name/hidden/groupName, not field)
|
|
QVERIFY(sensors->size() == 1);
|
|
QVERIFY(sensors->at(0).name == "New Name");
|
|
QVERIFY(sensors->at(0).hidden == true);
|
|
QVERIFY(sensors->at(0).field == 20.0); // Field unchanged from initial
|
|
}
|
|
|
|
void testSensorStoreNonUserUpdateIgnoresNameAndHidden()
|
|
{
|
|
// Create a SensorStore
|
|
SensorStore store;
|
|
store.getSensors()->clear();
|
|
|
|
// Add initial sensor
|
|
Sensor initialSensor(Sensor::TYPE_TEMPERATURE, 1, 20.0, "Initial Name", false);
|
|
store.sensorGotState(initialSensor, SENSOR_UPDATE_BACKEND);
|
|
|
|
// Verify initial state
|
|
std::vector<Sensor>* sensors = store.getSensors();
|
|
QVERIFY(sensors->size() == 1);
|
|
QVERIFY(sensors->at(0).name == "Initial Name");
|
|
QVERIFY(sensors->at(0).hidden == false);
|
|
|
|
// Send BACKEND update with new name and hidden state
|
|
Sensor backendUpdate(Sensor::TYPE_TEMPERATURE, 1, 25.0, "Backend Name", true);
|
|
store.sensorGotState(backendUpdate, SENSOR_UPDATE_BACKEND);
|
|
|
|
// Verify name and hidden were NOT updated
|
|
QVERIFY(sensors->size() == 1);
|
|
QVERIFY(sensors->at(0).name == "Initial Name");
|
|
QVERIFY(sensors->at(0).hidden == false);
|
|
QVERIFY(sensors->at(0).field == 25.0);
|
|
}
|
|
|
|
void testSensorStoreUserUpdateUpdatesKnownSensors()
|
|
{
|
|
// Create a SensorStore
|
|
SensorStore store;
|
|
store.getSensors()->clear();
|
|
|
|
// Add initial sensor
|
|
Sensor initialSensor(Sensor::TYPE_TEMPERATURE, 1, 20.0, "Initial Name", false);
|
|
store.sensorGotState(initialSensor, SENSOR_UPDATE_BACKEND);
|
|
|
|
// Send USER update with new name and hidden state
|
|
Sensor userUpdate(Sensor::TYPE_TEMPERATURE, 1, 25.0, "New Name", true);
|
|
store.sensorGotState(userUpdate, SENSOR_UPDATE_USER);
|
|
|
|
// Store to JSON and reload
|
|
QJsonObject json;
|
|
store.store(json);
|
|
|
|
SensorStore store2;
|
|
store2.getSensors()->clear();
|
|
store2.load(json);
|
|
|
|
// Add the sensor again - should use the updated name from knownSensors_
|
|
Sensor newSensor(Sensor::TYPE_TEMPERATURE, 1, 30.0, "Original Name", false);
|
|
store2.sensorGotState(newSensor, SENSOR_UPDATE_BACKEND);
|
|
|
|
// Verify the name was taken from knownSensors_
|
|
std::vector<Sensor>* sensors = store2.getSensors();
|
|
QVERIFY(sensors->size() == 1);
|
|
QVERIFY(sensors->at(0).name == "New Name");
|
|
QVERIFY(sensors->at(0).hidden == true);
|
|
}
|
|
|
|
void testSensorStoreNewSensorNotInKnownSensors()
|
|
{
|
|
// Create a SensorStore
|
|
SensorStore store;
|
|
store.getSensors()->clear();
|
|
|
|
// Add a new sensor (not in knownSensors_)
|
|
Sensor newSensor(Sensor::TYPE_TEMPERATURE, 99, 25.0, "New Sensor Name", true);
|
|
store.sensorGotState(newSensor, SENSOR_UPDATE_BACKEND);
|
|
|
|
// Verify sensor was added with its original name
|
|
std::vector<Sensor>* sensors = store.getSensors();
|
|
QVERIFY(sensors->size() == 1);
|
|
QVERIFY(sensors->at(0).name == "New Sensor Name");
|
|
QVERIFY(sensors->at(0).hidden == true);
|
|
}
|
|
|
|
void testSensorStoreNewSensorInKnownSensors()
|
|
{
|
|
// Create a SensorStore
|
|
SensorStore store;
|
|
store.getSensors()->clear();
|
|
|
|
// Load known sensors
|
|
QJsonObject json;
|
|
QJsonArray sensorsArray;
|
|
QJsonObject knownSensor;
|
|
knownSensor["SensorType"] = Sensor::TYPE_TEMPERATURE;
|
|
knownSensor["Id"] = 99;
|
|
knownSensor["Name"] = "Known Sensor Name";
|
|
knownSensor["Hidden"] = true;
|
|
sensorsArray.append(knownSensor);
|
|
json["Sensors"] = sensorsArray;
|
|
store.load(json);
|
|
|
|
// Add a new sensor that matches knownSensors_
|
|
Sensor newSensor(Sensor::TYPE_TEMPERATURE, 99, 25.0, "Original Name", false);
|
|
store.sensorGotState(newSensor, SENSOR_UPDATE_BACKEND);
|
|
|
|
// Verify name was overridden from knownSensors_
|
|
std::vector<Sensor>* sensors = store.getSensors();
|
|
QVERIFY(sensors->size() == 1);
|
|
QVERIFY(sensors->at(0).name == "Known Sensor Name");
|
|
QVERIFY(sensors->at(0).hidden == true);
|
|
}
|
|
|
|
void testSensorStoreRemoteUpdateIgnored()
|
|
{
|
|
// Create a SensorStore
|
|
SensorStore store;
|
|
store.getSensors()->clear();
|
|
|
|
// Add initial sensor
|
|
Sensor initialSensor(Sensor::TYPE_TEMPERATURE, 1, 20.0, "Initial Name", false);
|
|
store.sensorGotState(initialSensor, SENSOR_UPDATE_BACKEND);
|
|
|
|
// Send REMOTE update with new name and hidden state
|
|
Sensor remoteUpdate(Sensor::TYPE_TEMPERATURE, 1, 25.0, "Remote Name", true);
|
|
store.sensorGotState(remoteUpdate, SENSOR_UPDATE_REMOTE);
|
|
|
|
// Verify name and hidden were NOT updated
|
|
std::vector<Sensor>* sensors = store.getSensors();
|
|
QVERIFY(sensors->size() == 1);
|
|
QVERIFY(sensors->at(0).name == "Initial Name");
|
|
QVERIFY(sensors->at(0).hidden == false);
|
|
QVERIFY(sensors->at(0).field == 25.0);
|
|
}
|
|
|
|
void cleanupTestCase()
|
|
{
|
|
// Cleanup after all tests
|
|
}
|
|
};
|
|
|
|
QTEST_APPLESS_MAIN(TestSensor)
|
|
|
|
#include "test_sensor.moc"
|