#include "gtest/gtest.h" #include "alert_manager.hpp" #include #include using namespace std; // Mock time function for deterministic testing uint32_t mock_timestamp = 1640995200; // 2022-01-01 00:00:00 UTC // Mock the time function to return a fixed value extern "C" uint32_t time(nullptr) { return mock_timestamp; } // Helper function to get current timestamp uint32_t getCurrentTimestamp() { return mock_timestamp; } // Test fixture for AlertManager class AlertManagerTest : public ::testing::Test { protected: AlertManager alert_manager; void SetUp() override { mock_timestamp = 1640995200; alert_manager.initialize(); } void TearDown() override { // Reset state alert_manager.resetAllAlerts(); } }; // Test case: checkAltitudeAlert - Normal input test TEST_F(AlertManagerTest, testCheckAltitudeAlertNormalInput) { // Arrange float altitude = 80.0f; // Within normal range uint32_t timestamp = getCurrentTimestamp(); // Act alert_manager.checkAltitudeAlert(altitude, timestamp); // Assert EXPECT_FALSE(alert_manager.hasActiveAlerts()); EXPECT_EQ(alert_manager.getActiveAlerts().size(), 0); } // Test case: checkAltitudeAlert - Upper threshold exceeded TEST_F(AlertManagerTest, testCheckAltitudeAlertUpperThresholdExceeded) { // Arrange float altitude = 150.0f; // Above upper threshold (100.0f) uint32_t timestamp = getCurrentTimestamp(); // Act alert_manager.checkAltitudeAlert(altitude, timestamp); // Assert EXPECT_TRUE(alert_manager.hasActiveAlerts()); auto active_alerts = alert_manager.getActiveAlerts(); EXPECT_EQ(active_alerts.size(), 1); EXPECT_EQ(active_alerts[0].type, AlertType::ALTITUDE_UPPER); EXPECT_EQ(active_alerts[0].status, AlertStatus::ACTIVE); EXPECT_EQ(active_alerts[0].trigger_time, timestamp); } // Test case: checkAltitudeAlert - Lower threshold exceeded TEST_F(AlertManagerTest, testCheckAltitudeAlertLowerThresholdExceeded) { // Arrange float altitude = -60.0f; // Below lower threshold (-50.0f) uint32_t timestamp = getCurrentTimestamp(); // Act alert_manager.checkAltitudeAlert(altitude, timestamp); // Assert EXPECT_TRUE(alert_manager.hasActiveAlerts()); auto active_alerts = alert_manager.getActiveAlerts(); EXPECT_EQ(active_alerts.size(), 1); EXPECT_EQ(active_alerts[0].type, AlertType::ALTITUDE_LOWER); EXPECT_EQ(active_alerts[0].status, AlertStatus::ACTIVE); EXPECT_EQ(active_alerts[0].trigger_time, timestamp); } // Test case: checkAltitudeAlert - Recovery from upper threshold TEST_F(AlertManagerTest, testCheckAltitudeAlertUpperThresholdRecovery) { // Arrange float altitude_above = 150.0f; // Trigger alert float altitude_normal = 80.0f; // Recover uint32_t timestamp1 = getCurrentTimestamp(); uint32_t timestamp2 = getCurrentTimestamp() + 1; // Act alert_manager.checkAltitudeAlert(altitude_above, timestamp1); alert_manager.checkAltitudeAlert(altitude_normal, timestamp2); // Assert EXPECT_FALSE(alert_manager.hasActiveAlerts()); auto active_alerts = alert_manager.getActiveAlerts(); EXPECT_EQ(active_alerts.size(), 0); } // Test case: checkAltitudeAlert - Recovery from lower threshold TEST_F(AlertManagerTest, testCheckAltitudeAlertLowerThresholdRecovery) { // Arrange float altitude_below = -60.0f; // Trigger alert float altitude_normal = -40.0f; // Recover uint32_t timestamp1 = getCurrentTimestamp(); uint32_t timestamp2 = getCurrentTimestamp() + 1; // Act alert_manager.checkAltitudeAlert(altitude_below, timestamp1); alert_manager.checkAltitudeAlert(altitude_normal, timestamp2); // Assert EXPECT_FALSE(alert_manager.hasActiveAlerts()); auto active_alerts = alert_manager.getActiveAlerts(); EXPECT_EQ(active_alerts.size(), 0); } // Test case: setAltitudeThresholds - Normal input test TEST_F(AlertManagerTest, testSetAltitudeThresholdsNormalInput) { // Arrange float upper = 200.0f; float lower = -100.0f; // Act alert_manager.setAltitudeThresholds(upper, lower); // Assert EXPECT_EQ(alert_manager.getAltitudeThresholds().first, upper); EXPECT_EQ(alert_manager.getAltitudeThresholds().second, lower); EXPECT_FALSE(alert_manager.hasActiveAlerts()); } // Test case: setAltitudeThresholds - Invalid input (upper <= lower) TEST_F(AlertManagerTest, testSetAltitudeThresholdsInvalidInput) { // Arrange float upper = 50.0f; float lower = 100.0f; // Act & Assert EXPECT_NO_THROW(alert_manager.setAltitudeThresholds(upper, lower)); // Note: The function prints error but does not throw exception // So we cannot use EXPECT_THROW here. // Instead, verify that thresholds were not updated EXPECT_EQ(alert_manager.getAltitudeThresholds().first, 100.0f); // Still default EXPECT_EQ(alert_manager.getAltitudeThresholds().second, -50.0f); // Still default } // Test case: setAltitudeThresholds - Edge case: upper == lower TEST_F(AlertManagerTest, testSetAltitudeThresholdsEdgeCaseEqual) { // Arrange float upper = 100.0f; float lower = 100.0f; // Act alert_manager.setAltitudeThresholds(upper, lower); // Assert EXPECT_EQ(alert_manager.getAltitudeThresholds().first, 100.0f); EXPECT_EQ(alert_manager.getAltitudeThresholds().second, 100.0f); // But since upper <= lower, it should not be accepted // Verify no change in actual thresholds EXPECT_EQ(alert_manager.getAltitudeThresholds().first, 100.0f); EXPECT_EQ(alert_manager.getAltitudeThresholds().second, -50.0f); } // Test case: setAltitudeThresholds - Reset alerts after threshold change TEST_F(AlertManagerTest, testSetAltitudeThresholdsResetAlerts) { // Arrange float altitude = 150.0f; uint32_t timestamp = getCurrentTimestamp(); // Trigger an alert first alert_manager.checkAltitudeAlert(altitude, timestamp); EXPECT_TRUE(alert_manager.hasActiveAlerts()); // Change thresholds float new_upper = 200.0f; float new_lower = -100.0f; // Act alert_manager.setAltitudeThresholds(new_upper, new_lower); // Assert EXPECT_FALSE(alert_manager.hasActiveAlerts()); EXPECT_EQ(alert_manager.getActiveAlerts().size(), 0); } // Test case: checkAltitudeAlert - Multiple consecutive calls TEST_F(AlertManagerTest, testCheckAltitudeAlertMultipleCalls) { // Arrange float altitude = 150.0f; uint32_t timestamp = getCurrentTimestamp(); // Act alert_manager.checkAltitudeAlert(altitude, timestamp); alert_manager.checkAltitudeAlert(altitude, timestamp + 1); // Assert EXPECT_TRUE(alert_manager.hasActiveAlerts()); auto active_alerts = alert_manager.getActiveAlerts(); EXPECT_EQ(active_alerts.size(), 1); EXPECT_EQ(active_alerts[0].type, AlertType::ALTITUDE_UPPER); EXPECT_EQ(active_alerts[0].status, AlertStatus::ACTIVE); EXPECT_EQ(active_alerts[0].trigger_time, timestamp); } // Test case: setAltitudeThresholds - Valid input with negative values TEST_F(AlertManagerTest, testSetAltitudeThresholdsValidNegative) { // Arrange float upper = -10.0f; float lower = -50.0f; // Act alert_manager.setAltitudeThresholds(upper, lower); // Assert EXPECT_EQ(alert_manager.getAltitudeThresholds().first, upper); EXPECT_EQ(alert_manager.getAltitudeThresholds().second, lower); EXPECT_FALSE(alert_manager.hasActiveAlerts()); } // Test case: checkAltitudeAlert - Zero altitude TEST_F(AlertManagerTest, testCheckAltitudeAlertZeroAltitude) { // Arrange float altitude = 0.0f; uint32_t timestamp = getCurrentTimestamp(); // Act alert_manager.checkAltitudeAlert(altitude, timestamp); // Assert EXPECT_FALSE(alert_manager.hasActiveAlerts()); EXPECT_EQ(alert_manager.getActiveAlerts().size(), 0); } // Test case: setAltitudeThresholds - Max float values TEST_F(AlertManagerTest, testSetAltitudeThresholdsMaxFloat) { // Arrange float upper = std::numeric_limits::max(); float lower = std::numeric_limits::lowest(); // Act alert_manager.setAltitudeThresholds(upper, lower); // Assert EXPECT_EQ(alert_manager.getAltitudeThresholds().first, upper); EXPECT_EQ(alert_manager.getAltitudeThresholds().second, lower); EXPECT_FALSE(alert_manager.hasActiveAlerts()); } // Test case: checkAltitudeAlert - Altitude exactly at upper threshold TEST_F(AlertManagerTest, testCheckAltitudeAlertAtUpperThreshold) { // Arrange float altitude = 100.0f; // Exactly equal to upper threshold uint32_t timestamp = getCurrentTimestamp(); // Act alert_manager.checkAltitudeAlert(altitude, timestamp); // Assert EXPECT_FALSE(alert_manager.hasActiveAlerts()); EXPECT_EQ(alert_manager.getActiveAlerts().size(), 0); } // Test case: checkAltitudeAlert - Altitude exactly at lower threshold TEST_F(AlertManagerTest, testCheckAltitudeAlertAtLowerThreshold) { // Arrange float altitude = -50.0f; // Exactly equal to lower threshold uint32_t timestamp = getCurrentTimestamp(); // Act alert_manager.checkAltitudeAlert(altitude, timestamp); // Assert EXPECT_FALSE(alert_manager.hasActiveAlerts()); EXPECT_EQ(alert_manager.getActiveAlerts().size(), 0); }