diff --git a/test/test_meshpacket_serializer/modules/test_encrypted.h b/test/test_meshpacket_serializer/modules/test_encrypted.h deleted file mode 100644 index cff04be9a..000000000 --- a/test/test_meshpacket_serializer/modules/test_encrypted.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#include "test_helpers.h" - -// Test encrypted packet serialization (packet that cannot be deserialized) -void test_encrypted_packet_serialization() -{ - // Create a packet that looks encrypted (random data that won't decode) - uint8_t encrypted_data[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE}; - - meshtastic_MeshPacket packet = meshtastic_MeshPacket_init_zero; - packet.id = 12345; - packet.from = 0xAABBCCDD; - packet.to = 0xFFFFFFFF; - packet.channel = 0; - packet.hop_limit = 3; - packet.want_ack = false; - packet.priority = meshtastic_MeshPacket_Priority_UNSET; - packet.rx_time = 1609459200; - packet.rx_snr = 10.5f; - packet.hop_start = 3; - packet.rx_rssi = -85; - packet.delayed = meshtastic_MeshPacket_Delayed_NO_DELAY; - - // Set encrypted variant - packet.which_payload_variant = meshtastic_MeshPacket_encrypted_tag; - memcpy(packet.encrypted.bytes, encrypted_data, sizeof(encrypted_data)); - packet.encrypted.size = sizeof(encrypted_data); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Should have empty type for encrypted/undecryptable packets - TEST_ASSERT_TRUE(jsonObj.find("type") != jsonObj.end()); - TEST_ASSERT_EQUAL_STRING("", jsonObj["type"]->AsString().c_str()); - - delete root; -} diff --git a/test/test_meshpacket_serializer/modules/test_nodeinfo.h b/test/test_meshpacket_serializer/modules/test_nodeinfo.h deleted file mode 100644 index ce2b32be8..000000000 --- a/test/test_meshpacket_serializer/modules/test_nodeinfo.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include "test_helpers.h" - -// Helper function to create and encode user info -static size_t encode_user_info(uint8_t *buffer, size_t buffer_size) -{ - meshtastic_User user = meshtastic_User_init_zero; - strcpy(user.long_name, "Test User"); - strcpy(user.short_name, "TU"); - strcpy(user.id, "!abcd1234"); - user.hw_model = meshtastic_HardwareModel_TBEAM; - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, buffer_size); - pb_encode(&stream, &meshtastic_User_msg, &user); - return stream.bytes_written; -} - -// Test NODEINFO_APP port serialization -void test_nodeinfo_serialization() -{ - uint8_t buffer[128]; - size_t payload_size = encode_user_info(buffer, sizeof(buffer)); - - meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_NODEINFO_APP, buffer, payload_size); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Check message type - TEST_ASSERT_TRUE(jsonObj.find("type") != jsonObj.end()); - TEST_ASSERT_EQUAL_STRING("nodeinfo", jsonObj["type"]->AsString().c_str()); - - delete root; -} diff --git a/test/test_meshpacket_serializer/modules/test_position.h b/test/test_meshpacket_serializer/modules/test_position.h deleted file mode 100644 index 23c304d7b..000000000 --- a/test/test_meshpacket_serializer/modules/test_position.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include "test_helpers.h" - -// Helper function to create and encode position data -static size_t encode_position(uint8_t *buffer, size_t buffer_size) -{ - meshtastic_Position position = meshtastic_Position_init_zero; - position.latitude_i = 374428880; // 37.4428880 * 1e7 - position.longitude_i = -1221913440; // -122.1913440 * 1e7 - position.altitude = 100; - position.time = 1609459200; - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, buffer_size); - pb_encode(&stream, &meshtastic_Position_msg, &position); - return stream.bytes_written; -} - -// Test POSITION_APP port serialization -void test_position_serialization() -{ - uint8_t buffer[128]; - size_t payload_size = encode_position(buffer, sizeof(buffer)); - - meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_POSITION_APP, buffer, payload_size); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Check message type - TEST_ASSERT_TRUE(jsonObj.find("type") != jsonObj.end()); - TEST_ASSERT_EQUAL_STRING("position", jsonObj["type"]->AsString().c_str()); - - delete root; -} diff --git a/test/test_meshpacket_serializer/modules/test_telemetry.h b/test/test_meshpacket_serializer/modules/test_telemetry.h deleted file mode 100644 index 10b7b88a8..000000000 --- a/test/test_meshpacket_serializer/modules/test_telemetry.h +++ /dev/null @@ -1,517 +0,0 @@ -#pragma once -#include "test_helpers.h" - -// Helper function to create and encode device metrics -static size_t encode_telemetry_device_metrics(uint8_t *buffer, size_t buffer_size) -{ - meshtastic_Telemetry telemetry = meshtastic_Telemetry_init_zero; - telemetry.time = 1609459200; - telemetry.which_variant = meshtastic_Telemetry_device_metrics_tag; - telemetry.variant.device_metrics.battery_level = 85; - telemetry.variant.device_metrics.has_battery_level = true; - telemetry.variant.device_metrics.voltage = 3.7f; - telemetry.variant.device_metrics.has_voltage = true; - telemetry.variant.device_metrics.channel_utilization = 15.5f; - telemetry.variant.device_metrics.has_channel_utilization = true; - telemetry.variant.device_metrics.air_util_tx = 8.2f; - telemetry.variant.device_metrics.has_air_util_tx = true; - telemetry.variant.device_metrics.uptime_seconds = 12345; - telemetry.variant.device_metrics.has_uptime_seconds = true; - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, buffer_size); - pb_encode(&stream, &meshtastic_Telemetry_msg, &telemetry); - return stream.bytes_written; -} - -// Helper function to create and encode empty environment metrics (no fields set) -static size_t encode_telemetry_environment_metrics_empty(uint8_t *buffer, size_t buffer_size) -{ - meshtastic_Telemetry telemetry = meshtastic_Telemetry_init_zero; - telemetry.time = 1609459200; - telemetry.which_variant = meshtastic_Telemetry_environment_metrics_tag; - - // NO fields are set - all has_* flags remain false - // This tests that empty environment metrics don't produce any JSON fields - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, buffer_size); - pb_encode(&stream, &meshtastic_Telemetry_msg, &telemetry); - return stream.bytes_written; -} - -// Helper function to create environment metrics with ALL possible fields set -// This function should be updated whenever new fields are added to the protobuf -static size_t encode_telemetry_environment_metrics_all_fields(uint8_t *buffer, size_t buffer_size) -{ - meshtastic_Telemetry telemetry = meshtastic_Telemetry_init_zero; - telemetry.time = 1609459200; - telemetry.which_variant = meshtastic_Telemetry_environment_metrics_tag; - - // Basic environment metrics - telemetry.variant.environment_metrics.temperature = 23.5f; - telemetry.variant.environment_metrics.has_temperature = true; - telemetry.variant.environment_metrics.relative_humidity = 65.0f; - telemetry.variant.environment_metrics.has_relative_humidity = true; - telemetry.variant.environment_metrics.barometric_pressure = 1013.25f; - telemetry.variant.environment_metrics.has_barometric_pressure = true; - - // Gas and air quality - telemetry.variant.environment_metrics.gas_resistance = 50.5f; - telemetry.variant.environment_metrics.has_gas_resistance = true; - telemetry.variant.environment_metrics.iaq = 120; - telemetry.variant.environment_metrics.has_iaq = true; - - // Power measurements - telemetry.variant.environment_metrics.voltage = 3.3f; - telemetry.variant.environment_metrics.has_voltage = true; - telemetry.variant.environment_metrics.current = 0.5f; - telemetry.variant.environment_metrics.has_current = true; - - // Light measurements (ALL 4 types) - telemetry.variant.environment_metrics.lux = 450.0f; - telemetry.variant.environment_metrics.has_lux = true; - telemetry.variant.environment_metrics.white_lux = 380.0f; - telemetry.variant.environment_metrics.has_white_lux = true; - telemetry.variant.environment_metrics.ir_lux = 25.0f; - telemetry.variant.environment_metrics.has_ir_lux = true; - telemetry.variant.environment_metrics.uv_lux = 15.0f; - telemetry.variant.environment_metrics.has_uv_lux = true; - - // Distance measurement - telemetry.variant.environment_metrics.distance = 150.0f; - telemetry.variant.environment_metrics.has_distance = true; - - // Wind measurements (ALL 4 types) - telemetry.variant.environment_metrics.wind_direction = 180; - telemetry.variant.environment_metrics.has_wind_direction = true; - telemetry.variant.environment_metrics.wind_speed = 5.5f; - telemetry.variant.environment_metrics.has_wind_speed = true; - telemetry.variant.environment_metrics.wind_gust = 8.2f; - telemetry.variant.environment_metrics.has_wind_gust = true; - telemetry.variant.environment_metrics.wind_lull = 2.1f; - telemetry.variant.environment_metrics.has_wind_lull = true; - - // Weight measurement - telemetry.variant.environment_metrics.weight = 75.5f; - telemetry.variant.environment_metrics.has_weight = true; - - // Radiation measurement - telemetry.variant.environment_metrics.radiation = 0.12f; - telemetry.variant.environment_metrics.has_radiation = true; - - // Rainfall measurements (BOTH types) - telemetry.variant.environment_metrics.rainfall_1h = 2.5f; - telemetry.variant.environment_metrics.has_rainfall_1h = true; - telemetry.variant.environment_metrics.rainfall_24h = 15.8f; - telemetry.variant.environment_metrics.has_rainfall_24h = true; - - // Soil measurements (BOTH types) - telemetry.variant.environment_metrics.soil_moisture = 85; - telemetry.variant.environment_metrics.has_soil_moisture = true; - telemetry.variant.environment_metrics.soil_temperature = 18.5f; - telemetry.variant.environment_metrics.has_soil_temperature = true; - - // IMPORTANT: When new environment fields are added to the protobuf, - // they MUST be added here too, or the coverage test will fail! - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, buffer_size); - pb_encode(&stream, &meshtastic_Telemetry_msg, &telemetry); - return stream.bytes_written; -} - -// Helper function to create and encode environment metrics with all current fields -static size_t encode_telemetry_environment_metrics(uint8_t *buffer, size_t buffer_size) -{ - meshtastic_Telemetry telemetry = meshtastic_Telemetry_init_zero; - telemetry.time = 1609459200; - telemetry.which_variant = meshtastic_Telemetry_environment_metrics_tag; - - // Basic environment metrics - telemetry.variant.environment_metrics.temperature = 23.5f; - telemetry.variant.environment_metrics.has_temperature = true; - telemetry.variant.environment_metrics.relative_humidity = 65.0f; - telemetry.variant.environment_metrics.has_relative_humidity = true; - telemetry.variant.environment_metrics.barometric_pressure = 1013.25f; - telemetry.variant.environment_metrics.has_barometric_pressure = true; - - // Gas and air quality - telemetry.variant.environment_metrics.gas_resistance = 50.5f; - telemetry.variant.environment_metrics.has_gas_resistance = true; - telemetry.variant.environment_metrics.iaq = 120; - telemetry.variant.environment_metrics.has_iaq = true; - - // Power measurements - telemetry.variant.environment_metrics.voltage = 3.3f; - telemetry.variant.environment_metrics.has_voltage = true; - telemetry.variant.environment_metrics.current = 0.5f; - telemetry.variant.environment_metrics.has_current = true; - - // Light measurements - telemetry.variant.environment_metrics.lux = 450.0f; - telemetry.variant.environment_metrics.has_lux = true; - telemetry.variant.environment_metrics.white_lux = 380.0f; - telemetry.variant.environment_metrics.has_white_lux = true; - telemetry.variant.environment_metrics.ir_lux = 25.0f; - telemetry.variant.environment_metrics.has_ir_lux = true; - telemetry.variant.environment_metrics.uv_lux = 15.0f; - telemetry.variant.environment_metrics.has_uv_lux = true; - - // Distance measurement - telemetry.variant.environment_metrics.distance = 150.0f; - telemetry.variant.environment_metrics.has_distance = true; - - // Wind measurements - telemetry.variant.environment_metrics.wind_direction = 180; - telemetry.variant.environment_metrics.has_wind_direction = true; - telemetry.variant.environment_metrics.wind_speed = 5.5f; - telemetry.variant.environment_metrics.has_wind_speed = true; - telemetry.variant.environment_metrics.wind_gust = 8.2f; - telemetry.variant.environment_metrics.has_wind_gust = true; - telemetry.variant.environment_metrics.wind_lull = 2.1f; - telemetry.variant.environment_metrics.has_wind_lull = true; - - // Weight measurement - telemetry.variant.environment_metrics.weight = 75.5f; - telemetry.variant.environment_metrics.has_weight = true; - - // Radiation measurement - telemetry.variant.environment_metrics.radiation = 0.12f; - telemetry.variant.environment_metrics.has_radiation = true; - - // Rainfall measurements - telemetry.variant.environment_metrics.rainfall_1h = 2.5f; - telemetry.variant.environment_metrics.has_rainfall_1h = true; - telemetry.variant.environment_metrics.rainfall_24h = 15.8f; - telemetry.variant.environment_metrics.has_rainfall_24h = true; - - // Soil measurements - telemetry.variant.environment_metrics.soil_moisture = 85; - telemetry.variant.environment_metrics.has_soil_moisture = true; - telemetry.variant.environment_metrics.soil_temperature = 18.5f; - telemetry.variant.environment_metrics.has_soil_temperature = true; - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, buffer_size); - pb_encode(&stream, &meshtastic_Telemetry_msg, &telemetry); - return stream.bytes_written; -} - -// Test TELEMETRY_APP port with device metrics -void test_telemetry_device_metrics_serialization() -{ - uint8_t buffer[256]; - size_t payload_size = encode_telemetry_device_metrics(buffer, sizeof(buffer)); - - meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_TELEMETRY_APP, buffer, payload_size); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Check message type - TEST_ASSERT_TRUE(jsonObj.find("type") != jsonObj.end()); - TEST_ASSERT_EQUAL_STRING("telemetry", jsonObj["type"]->AsString().c_str()); - - // Check payload - TEST_ASSERT_TRUE(jsonObj.find("payload") != jsonObj.end()); - TEST_ASSERT_TRUE(jsonObj["payload"]->IsObject()); - - JSONObject payload = jsonObj["payload"]->AsObject(); - - // Verify telemetry data - TEST_ASSERT_TRUE(payload.find("battery_level") != payload.end()); - TEST_ASSERT_EQUAL(85, (int)payload["battery_level"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("voltage") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 3.7f, payload["voltage"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("channel_utilization") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 15.5f, payload["channel_utilization"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("uptime_seconds") != payload.end()); - TEST_ASSERT_EQUAL(12345, (int)payload["uptime_seconds"]->AsNumber()); - - delete root; -} - -// Test that telemetry environment metrics are properly serialized -void test_telemetry_environment_metrics_serialization() -{ - uint8_t buffer[256]; - size_t payload_size = encode_telemetry_environment_metrics(buffer, sizeof(buffer)); - - meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_TELEMETRY_APP, buffer, payload_size); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Check payload exists - TEST_ASSERT_TRUE(jsonObj.find("payload") != jsonObj.end()); - TEST_ASSERT_TRUE(jsonObj["payload"]->IsObject()); - - JSONObject payload = jsonObj["payload"]->AsObject(); - - // Test key fields that should be present in the serializer - TEST_ASSERT_TRUE(payload.find("temperature") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 23.5f, payload["temperature"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("relative_humidity") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 65.0f, payload["relative_humidity"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("distance") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 150.0f, payload["distance"]->AsNumber()); - - delete root; -} - -// Test comprehensive environment metrics coverage -void test_telemetry_environment_metrics_comprehensive() -{ - uint8_t buffer[256]; - size_t payload_size = encode_telemetry_environment_metrics(buffer, sizeof(buffer)); - - meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_TELEMETRY_APP, buffer, payload_size); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Check payload exists - TEST_ASSERT_TRUE(jsonObj.find("payload") != jsonObj.end()); - TEST_ASSERT_TRUE(jsonObj["payload"]->IsObject()); - - JSONObject payload = jsonObj["payload"]->AsObject(); - - // Check all 15 originally supported fields - TEST_ASSERT_TRUE(payload.find("temperature") != payload.end()); - TEST_ASSERT_TRUE(payload.find("relative_humidity") != payload.end()); - TEST_ASSERT_TRUE(payload.find("barometric_pressure") != payload.end()); - TEST_ASSERT_TRUE(payload.find("gas_resistance") != payload.end()); - TEST_ASSERT_TRUE(payload.find("voltage") != payload.end()); - TEST_ASSERT_TRUE(payload.find("current") != payload.end()); - TEST_ASSERT_TRUE(payload.find("iaq") != payload.end()); - TEST_ASSERT_TRUE(payload.find("distance") != payload.end()); - TEST_ASSERT_TRUE(payload.find("lux") != payload.end()); - TEST_ASSERT_TRUE(payload.find("white_lux") != payload.end()); - TEST_ASSERT_TRUE(payload.find("wind_direction") != payload.end()); - TEST_ASSERT_TRUE(payload.find("wind_speed") != payload.end()); - TEST_ASSERT_TRUE(payload.find("wind_gust") != payload.end()); - TEST_ASSERT_TRUE(payload.find("wind_lull") != payload.end()); - TEST_ASSERT_TRUE(payload.find("radiation") != payload.end()); - - delete root; -} - -// Test for the 7 environment fields that were added to complete coverage -void test_telemetry_environment_metrics_missing_fields() -{ - uint8_t buffer[256]; - size_t payload_size = encode_telemetry_environment_metrics(buffer, sizeof(buffer)); - - meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_TELEMETRY_APP, buffer, payload_size); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Check payload exists - TEST_ASSERT_TRUE(jsonObj.find("payload") != jsonObj.end()); - TEST_ASSERT_TRUE(jsonObj["payload"]->IsObject()); - - JSONObject payload = jsonObj["payload"]->AsObject(); - - // Check the 7 fields that were previously missing - TEST_ASSERT_TRUE(payload.find("ir_lux") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 25.0f, payload["ir_lux"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("uv_lux") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 15.0f, payload["uv_lux"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("weight") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 75.5f, payload["weight"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("rainfall_1h") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 2.5f, payload["rainfall_1h"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("rainfall_24h") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 15.8f, payload["rainfall_24h"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("soil_moisture") != payload.end()); - TEST_ASSERT_EQUAL(85, (int)payload["soil_moisture"]->AsNumber()); - - TEST_ASSERT_TRUE(payload.find("soil_temperature") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 18.5f, payload["soil_temperature"]->AsNumber()); - - delete root; -} - -// Test that ALL environment fields are serialized (canary test for forgotten fields) -// This test will FAIL if a new environment field is added to the protobuf but not to the serializer -void test_telemetry_environment_metrics_complete_coverage() -{ - uint8_t buffer[256]; - size_t payload_size = encode_telemetry_environment_metrics_all_fields(buffer, sizeof(buffer)); - - meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_TELEMETRY_APP, buffer, payload_size); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Check payload exists - TEST_ASSERT_TRUE(jsonObj.find("payload") != jsonObj.end()); - TEST_ASSERT_TRUE(jsonObj["payload"]->IsObject()); - - JSONObject payload = jsonObj["payload"]->AsObject(); - - // ✅ ALL 22 environment fields MUST be present and correct - // If this test fails, it means either: - // 1. A new field was added to the protobuf but not to the serializer - // 2. The encode_telemetry_environment_metrics_all_fields() function wasn't updated - - // Basic environment (3 fields) - TEST_ASSERT_TRUE(payload.find("temperature") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 23.5f, payload["temperature"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("relative_humidity") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 65.0f, payload["relative_humidity"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("barometric_pressure") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 1013.25f, payload["barometric_pressure"]->AsNumber()); - - // Gas and air quality (2 fields) - TEST_ASSERT_TRUE(payload.find("gas_resistance") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 50.5f, payload["gas_resistance"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("iaq") != payload.end()); - TEST_ASSERT_EQUAL(120, (int)payload["iaq"]->AsNumber()); - - // Power measurements (2 fields) - TEST_ASSERT_TRUE(payload.find("voltage") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 3.3f, payload["voltage"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("current") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.5f, payload["current"]->AsNumber()); - - // Light measurements (4 fields) - TEST_ASSERT_TRUE(payload.find("lux") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 450.0f, payload["lux"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("white_lux") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 380.0f, payload["white_lux"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("ir_lux") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 25.0f, payload["ir_lux"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("uv_lux") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 15.0f, payload["uv_lux"]->AsNumber()); - - // Distance measurement (1 field) - TEST_ASSERT_TRUE(payload.find("distance") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 150.0f, payload["distance"]->AsNumber()); - - // Wind measurements (4 fields) - TEST_ASSERT_TRUE(payload.find("wind_direction") != payload.end()); - TEST_ASSERT_EQUAL(180, (int)payload["wind_direction"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("wind_speed") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 5.5f, payload["wind_speed"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("wind_gust") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 8.2f, payload["wind_gust"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("wind_lull") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 2.1f, payload["wind_lull"]->AsNumber()); - - // Weight measurement (1 field) - TEST_ASSERT_TRUE(payload.find("weight") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 75.5f, payload["weight"]->AsNumber()); - - // Radiation measurement (1 field) - TEST_ASSERT_TRUE(payload.find("radiation") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.12f, payload["radiation"]->AsNumber()); - - // Rainfall measurements (2 fields) - TEST_ASSERT_TRUE(payload.find("rainfall_1h") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 2.5f, payload["rainfall_1h"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("rainfall_24h") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 15.8f, payload["rainfall_24h"]->AsNumber()); - - // Soil measurements (2 fields) - TEST_ASSERT_TRUE(payload.find("soil_moisture") != payload.end()); - TEST_ASSERT_EQUAL(85, (int)payload["soil_moisture"]->AsNumber()); - TEST_ASSERT_TRUE(payload.find("soil_temperature") != payload.end()); - TEST_ASSERT_FLOAT_WITHIN(0.01f, 18.5f, payload["soil_temperature"]->AsNumber()); - - // Total: 22 environment fields - // This test ensures 100% coverage of environment metrics - - delete root; -} - -// Test that unset environment fields are not present in JSON -void test_telemetry_environment_metrics_unset_fields() -{ - uint8_t buffer[256]; - size_t payload_size = encode_telemetry_environment_metrics_empty(buffer, sizeof(buffer)); - - meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_TELEMETRY_APP, buffer, payload_size); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Check payload exists - TEST_ASSERT_TRUE(jsonObj.find("payload") != jsonObj.end()); - TEST_ASSERT_TRUE(jsonObj["payload"]->IsObject()); - - JSONObject payload = jsonObj["payload"]->AsObject(); - - // With completely empty environment metrics, NO fields should be present - // Only basic telemetry fields like "time" might be present - - // All 22 environment fields should be absent (none were set) - TEST_ASSERT_TRUE(payload.find("temperature") == payload.end()); - TEST_ASSERT_TRUE(payload.find("relative_humidity") == payload.end()); - TEST_ASSERT_TRUE(payload.find("barometric_pressure") == payload.end()); - TEST_ASSERT_TRUE(payload.find("gas_resistance") == payload.end()); - TEST_ASSERT_TRUE(payload.find("iaq") == payload.end()); - TEST_ASSERT_TRUE(payload.find("voltage") == payload.end()); - TEST_ASSERT_TRUE(payload.find("current") == payload.end()); - TEST_ASSERT_TRUE(payload.find("lux") == payload.end()); - TEST_ASSERT_TRUE(payload.find("white_lux") == payload.end()); - TEST_ASSERT_TRUE(payload.find("ir_lux") == payload.end()); - TEST_ASSERT_TRUE(payload.find("uv_lux") == payload.end()); - TEST_ASSERT_TRUE(payload.find("distance") == payload.end()); - TEST_ASSERT_TRUE(payload.find("wind_direction") == payload.end()); - TEST_ASSERT_TRUE(payload.find("wind_speed") == payload.end()); - TEST_ASSERT_TRUE(payload.find("wind_gust") == payload.end()); - TEST_ASSERT_TRUE(payload.find("wind_lull") == payload.end()); - TEST_ASSERT_TRUE(payload.find("weight") == payload.end()); - TEST_ASSERT_TRUE(payload.find("radiation") == payload.end()); - TEST_ASSERT_TRUE(payload.find("rainfall_1h") == payload.end()); - TEST_ASSERT_TRUE(payload.find("rainfall_24h") == payload.end()); - TEST_ASSERT_TRUE(payload.find("soil_moisture") == payload.end()); - TEST_ASSERT_TRUE(payload.find("soil_temperature") == payload.end()); - - delete root; -} diff --git a/test/test_meshpacket_serializer/modules/test_text_message.h b/test/test_meshpacket_serializer/modules/test_text_message.h deleted file mode 100644 index 22cf3b0b8..000000000 --- a/test/test_meshpacket_serializer/modules/test_text_message.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include "test_helpers.h" - -// Test TEXT_MESSAGE_APP port serialization -void test_text_message_serialization() -{ - const char *message = "Hello, Mesh!"; - - meshtastic_MeshPacket packet = - create_test_packet(meshtastic_PortNum_TEXT_MESSAGE_APP, (const uint8_t *)message, strlen(message)); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Check message type - TEST_ASSERT_TRUE(jsonObj.find("type") != jsonObj.end()); - TEST_ASSERT_EQUAL_STRING("text", jsonObj["type"]->AsString().c_str()); - - // Check payload - TEST_ASSERT_TRUE(jsonObj.find("payload") != jsonObj.end()); - TEST_ASSERT_TRUE(jsonObj["payload"]->IsObject()); - - JSONObject payload = jsonObj["payload"]->AsObject(); - TEST_ASSERT_TRUE(payload.find("text") != payload.end()); - TEST_ASSERT_EQUAL_STRING(message, payload["text"]->AsString().c_str()); - - delete root; -} diff --git a/test/test_meshpacket_serializer/modules/test_waypoint.h b/test/test_meshpacket_serializer/modules/test_waypoint.h deleted file mode 100644 index d99aa92e8..000000000 --- a/test/test_meshpacket_serializer/modules/test_waypoint.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include "test_helpers.h" - -// Helper function to create and encode waypoint data -static size_t encode_waypoint(uint8_t *buffer, size_t buffer_size) -{ - meshtastic_Waypoint waypoint = meshtastic_Waypoint_init_zero; - waypoint.id = 12345; - waypoint.latitude_i = 374428880; // 37.4428880 * 1e7 - waypoint.longitude_i = -1221913440; // -122.1913440 * 1e7 - waypoint.expire = 1640995200; // Expiry time - strcpy(waypoint.name, "Test Waypoint"); - strcpy(waypoint.description, "A test waypoint for unit testing"); - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, buffer_size); - pb_encode(&stream, &meshtastic_Waypoint_msg, &waypoint); - return stream.bytes_written; -} - -// Test WAYPOINT_APP port serialization -void test_waypoint_serialization() -{ - uint8_t buffer[256]; - size_t payload_size = encode_waypoint(buffer, sizeof(buffer)); - - meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_WAYPOINT_APP, buffer, payload_size); - - std::string json = MeshPacketSerializer::JsonSerialize(&packet, false); - TEST_ASSERT_TRUE(json.length() > 0); - - JSONValue *root = JSON::Parse(json.c_str()); - TEST_ASSERT_NOT_NULL(root); - TEST_ASSERT_TRUE(root->IsObject()); - - JSONObject jsonObj = root->AsObject(); - - // Check message type - TEST_ASSERT_TRUE(jsonObj.find("type") != jsonObj.end()); - TEST_ASSERT_EQUAL_STRING("waypoint", jsonObj["type"]->AsString().c_str()); - - delete root; -} diff --git a/test/test_meshpacket_serializer/test_main.cpp b/test/test_meshpacket_serializer/test_main.cpp deleted file mode 100644 index 2bf68bb53..000000000 --- a/test/test_meshpacket_serializer/test_main.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include - -// Include modular test modules -#include "modules/test_encrypted.h" -#include "modules/test_nodeinfo.h" -#include "modules/test_position.h" -#include "modules/test_telemetry.h" -#include "modules/test_text_message.h" -#include "modules/test_waypoint.h" - -void setup() -{ - UNITY_BEGIN(); - - // Text message tests - RUN_TEST(test_text_message_serialization); - - // Position tests - RUN_TEST(test_position_serialization); - - // Nodeinfo tests - RUN_TEST(test_nodeinfo_serialization); - - // Waypoint tests - RUN_TEST(test_waypoint_serialization); - - // Telemetry tests - RUN_TEST(test_telemetry_device_metrics_serialization); - RUN_TEST(test_telemetry_environment_metrics_serialization); - RUN_TEST(test_telemetry_environment_metrics_comprehensive); - RUN_TEST(test_telemetry_environment_metrics_missing_fields); - RUN_TEST(test_telemetry_environment_metrics_complete_coverage); - RUN_TEST(test_telemetry_environment_metrics_unset_fields); - - // Encrypted packet test - RUN_TEST(test_encrypted_packet_serialization); - - UNITY_END(); -} - -void loop() -{ - delay(1000); -} diff --git a/test/test_meshpacket_serializer/test_main_new.cpp b/test/test_meshpacket_serializer/test_serializer.cpp similarity index 100% rename from test/test_meshpacket_serializer/test_main_new.cpp rename to test/test_meshpacket_serializer/test_serializer.cpp