#include #include struct TestConfig { char wifi_ssid[33]; char wifi_password[65]; char mqtt_broker[65]; uint16_t mqtt_port; uint8_t modbus_address; uint32_t modbus_baud; uint16_t poll_interval_sec; uint8_t transport_priority; }; static bool validateConfig(TestConfig& cfg) { if (strlen(cfg.wifi_ssid) == 0) return false; if (cfg.mqtt_port == 0 || cfg.mqtt_port > 65535) return false; if (cfg.modbus_address == 0 || cfg.modbus_address > 247) return false; if (cfg.modbus_baud != 9600 && cfg.modbus_baud != 19200 && cfg.modbus_baud != 38400 && cfg.modbus_baud != 57600 && cfg.modbus_baud != 115200) return false; if (cfg.poll_interval_sec < 1 || cfg.poll_interval_sec > 3600) return false; if (cfg.transport_priority > 3) return false; return true; } void test_valid_config() { TestConfig cfg; strncpy(cfg.wifi_ssid, "TestNetwork", sizeof(cfg.wifi_ssid)); strncpy(cfg.wifi_password, "password123", sizeof(cfg.wifi_password)); strncpy(cfg.mqtt_broker, "broker.example.com", sizeof(cfg.mqtt_broker)); cfg.mqtt_port = 1883; cfg.modbus_address = 1; cfg.modbus_baud = 9600; cfg.poll_interval_sec = 5; cfg.transport_priority = 0; TEST_ASSERT_TRUE(validateConfig(cfg)); } void test_empty_ssid_invalid() { TestConfig cfg = {}; cfg.mqtt_port = 1883; cfg.modbus_address = 1; cfg.modbus_baud = 9600; cfg.poll_interval_sec = 5; TEST_ASSERT_FALSE(validateConfig(cfg)); } void test_invalid_modbus_address() { TestConfig cfg; strncpy(cfg.wifi_ssid, "TestNetwork", sizeof(cfg.wifi_ssid)); cfg.mqtt_port = 1883; cfg.modbus_address = 0; cfg.modbus_baud = 9600; cfg.poll_interval_sec = 5; cfg.transport_priority = 0; TEST_ASSERT_FALSE(validateConfig(cfg)); cfg.modbus_address = 248; TEST_ASSERT_FALSE(validateConfig(cfg)); } void test_invalid_baud_rate() { TestConfig cfg; strncpy(cfg.wifi_ssid, "TestNetwork", sizeof(cfg.wifi_ssid)); cfg.mqtt_port = 1883; cfg.modbus_address = 1; cfg.modbus_baud = 12345; cfg.poll_interval_sec = 5; cfg.transport_priority = 0; TEST_ASSERT_FALSE(validateConfig(cfg)); } void test_poll_interval_bounds() { TestConfig cfg; strncpy(cfg.wifi_ssid, "TestNetwork", sizeof(cfg.wifi_ssid)); cfg.mqtt_port = 1883; cfg.modbus_address = 1; cfg.modbus_baud = 9600; cfg.transport_priority = 0; cfg.poll_interval_sec = 0; TEST_ASSERT_FALSE(validateConfig(cfg)); cfg.poll_interval_sec = 3601; TEST_ASSERT_FALSE(validateConfig(cfg)); cfg.poll_interval_sec = 1; TEST_ASSERT_TRUE(validateConfig(cfg)); cfg.poll_interval_sec = 3600; TEST_ASSERT_TRUE(validateConfig(cfg)); } void test_config_from_json() { const char* json = R"({"wifi":{"ssid":"TestNet","password":"pass123"},"mqtt":{"broker":"mqtt.test","port":8883},"modbus":{"address":5,"baud":19200,"poll_interval":10}})"; JsonDocument doc; DeserializationError err = deserializeJson(doc, json); TEST_ASSERT_EQUAL(DeserializationError::Ok, err); TestConfig cfg = {}; strncpy(cfg.wifi_ssid, doc["wifi"]["ssid"] | "", sizeof(cfg.wifi_ssid)); strncpy(cfg.wifi_password, doc["wifi"]["password"] | "", sizeof(cfg.wifi_password)); strncpy(cfg.mqtt_broker, doc["mqtt"]["broker"] | "", sizeof(cfg.mqtt_broker)); cfg.mqtt_port = doc["mqtt"]["port"] | 1883; cfg.modbus_address = doc["modbus"]["address"] | 1; cfg.modbus_baud = doc["modbus"]["baud"] | 9600; cfg.poll_interval_sec = doc["modbus"]["poll_interval"] | 5; cfg.transport_priority = 0; TEST_ASSERT_EQUAL_STRING("TestNet", cfg.wifi_ssid); TEST_ASSERT_EQUAL(8883, cfg.mqtt_port); TEST_ASSERT_EQUAL(5, cfg.modbus_address); TEST_ASSERT_EQUAL(19200, cfg.modbus_baud); TEST_ASSERT_EQUAL(10, cfg.poll_interval_sec); TEST_ASSERT_TRUE(validateConfig(cfg)); } void test_config_to_json() { TestConfig cfg; strncpy(cfg.wifi_ssid, "MyNetwork", sizeof(cfg.wifi_ssid)); strncpy(cfg.mqtt_broker, "broker.local", sizeof(cfg.mqtt_broker)); cfg.mqtt_port = 1883; cfg.modbus_address = 1; cfg.modbus_baud = 9600; cfg.poll_interval_sec = 5; JsonDocument doc; JsonObject root = doc.to(); root["wifi"]["ssid"] = cfg.wifi_ssid; root["mqtt"]["broker"] = cfg.mqtt_broker; root["mqtt"]["port"] = cfg.mqtt_port; root["modbus"]["address"] = cfg.modbus_address; root["modbus"]["baud"] = cfg.modbus_baud; root["modbus"]["poll_interval"] = cfg.poll_interval_sec; String output; serializeJson(doc, output); TEST_ASSERT_TRUE(output.indexOf("MyNetwork") >= 0); TEST_ASSERT_TRUE(output.indexOf("1883") >= 0); } void setup() { delay(2000); UNITY_BEGIN(); RUN_TEST(test_valid_config); RUN_TEST(test_empty_ssid_invalid); RUN_TEST(test_invalid_modbus_address); RUN_TEST(test_invalid_baud_rate); RUN_TEST(test_poll_interval_bounds); RUN_TEST(test_config_from_json); RUN_TEST(test_config_to_json); UNITY_END(); } void loop() {}