#!/usr/bin/env python3 """ Test script to verify the template matching algorithm in TasmotaManager.py. This script simulates different scenarios to ensure the algorithm works correctly: 1. Key matches Device Name, Template matches value 2. Key matches Device Name, Template doesn't match value 3. No key matches Device Name, but a value matches Template 4. No matches at all """ import json import logging import requests import unittest from unittest.mock import patch, MagicMock # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) logger = logging.getLogger(__name__) # Import TasmotaManager class import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) from TasmotaManager import TasmotaDiscovery class TestTemplateMatching(unittest.TestCase): """Test cases for template matching algorithm.""" def setUp(self): """Set up test environment.""" self.discovery = TasmotaDiscovery(debug=True) # Create a mock config with mqtt.config_other self.discovery.config = { 'mqtt': { 'config_other': { 'TreatLife_SW_SS01S': '{"NAME":"TL SS01S Swtch","GPIO":[0,0,0,0,52,158,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}', 'TreatLife_SW_SS02S': '{"NAME":"Treatlife SS02","GPIO":[0,0,0,0,288,576,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}' } } } @patch('requests.get') def test_key_matches_template_matches(self, mock_get): """Test when key matches Device Name and template matches value.""" # Mock responses for Status 0 and Template commands mock_responses = [ # Status 0 response MagicMock( status_code=200, json=lambda: {"Status": {"DeviceName": "TreatLife_SW_SS01S"}} ), # Template response MagicMock( status_code=200, json=lambda: {"Template": '{"NAME":"TL SS01S Swtch","GPIO":[0,0,0,0,52,158,0,0,21,17,0,0,0],"FLAG":0,"BASE":18}'} ) ] mock_get.side_effect = mock_responses # Call the method result = self.discovery.check_and_update_template("192.168.8.100", "test_device") # Verify results self.assertFalse(result) # No update needed self.assertEqual(mock_get.call_count, 2) # Only Status 0 and Template calls # Log the result logger.info("Test 1: Key matches Device Name, Template matches value - PASSED") @patch('requests.get') def test_key_matches_template_doesnt_match(self, mock_get): """Test when key matches Device Name but template doesn't match value.""" # Mock responses for Status 0, Template, and Template update commands mock_responses = [ # Status 0 response MagicMock( status_code=200, json=lambda: {"Status": {"DeviceName": "TreatLife_SW_SS01S"}} ), # Template response MagicMock( status_code=200, json=lambda: {"Template": '{"NAME":"Different Template","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}'} ), # Template update response MagicMock( status_code=200, json=lambda: {"Template": "Done"} ) ] mock_get.side_effect = mock_responses # Call the method result = self.discovery.check_and_update_template("192.168.8.100", "test_device") # Verify results self.assertTrue(result) # Template was updated self.assertEqual(mock_get.call_count, 3) # Status 0, Template, and Template update calls # Log the result logger.info("Test 2: Key matches Device Name, Template doesn't match value - PASSED") @patch('requests.get') def test_no_key_matches_value_matches(self, mock_get): """Test when no key matches Device Name but a value matches Template.""" # Mock responses for Status 0, Template, and DeviceName update commands mock_responses = [ # Status 0 response MagicMock( status_code=200, json=lambda: {"Status": {"DeviceName": "Unknown_Device"}} ), # Template response MagicMock( status_code=200, json=lambda: {"Template": '{"NAME":"Treatlife SS02","GPIO":[0,0,0,0,288,576,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}'} ), # DeviceName update response MagicMock( status_code=200, json=lambda: {"DeviceName": "Done"} ) ] mock_get.side_effect = mock_responses # Call the method result = self.discovery.check_and_update_template("192.168.8.100", "test_device") # Verify results self.assertTrue(result) # Device name was updated self.assertEqual(mock_get.call_count, 3) # Status 0, Template, and DeviceName update calls # Log the result logger.info("Test 3: No key matches Device Name, but a value matches Template - PASSED") @patch('requests.get') def test_no_matches_at_all(self, mock_get): """Test when there are no matches at all.""" # Mock responses for Status 0 and Template commands mock_responses = [ # Status 0 response MagicMock( status_code=200, json=lambda: {"Status": {"DeviceName": "Unknown_Device"}} ), # Template response MagicMock( status_code=200, json=lambda: {"Template": '{"NAME":"Unknown Template","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}'} ) ] mock_get.side_effect = mock_responses # Call the method result = self.discovery.check_and_update_template("192.168.8.100", "test_device") # Verify results self.assertFalse(result) # No updates made self.assertEqual(mock_get.call_count, 2) # Only Status 0 and Template calls # Log the result logger.info("Test 4: No matches at all - PASSED") @patch('requests.get') def test_no_config_other(self, mock_get): """Test when there's no mqtt.config_other in the configuration.""" # Set empty config_other self.discovery.config = {'mqtt': {}} # Call the method result = self.discovery.check_and_update_template("192.168.8.100", "test_device") # Verify results self.assertFalse(result) # No updates made self.assertEqual(mock_get.call_count, 0) # No HTTP calls made # Log the result logger.info("Test 5: No mqtt.config_other in configuration - PASSED") @patch('requests.get') def test_status0_failure(self, mock_get): """Test when Status 0 command fails.""" # Mock response for Status 0 command mock_get.return_value = MagicMock( status_code=200, json=lambda: {"Status": {}} # Missing DeviceName ) # Call the method result = self.discovery.check_and_update_template("192.168.8.100", "test_device") # Verify results self.assertFalse(result) # No updates made self.assertEqual(mock_get.call_count, 1) # Only Status 0 call # Log the result logger.info("Test 6: Status 0 command failure - PASSED") @patch('requests.get') def test_template_failure(self, mock_get): """Test when Template command fails.""" # Mock responses for Status 0 and Template commands mock_responses = [ # Status 0 response MagicMock( status_code=200, json=lambda: {"Status": {"DeviceName": "TreatLife_SW_SS01S"}} ), # Template response MagicMock( status_code=200, json=lambda: {} # Missing Template ) ] mock_get.side_effect = mock_responses # Call the method result = self.discovery.check_and_update_template("192.168.8.100", "test_device") # Verify results self.assertFalse(result) # No updates made self.assertEqual(mock_get.call_count, 2) # Status 0 and Template calls # Log the result logger.info("Test 7: Template command failure - PASSED") def main(): """Run the tests.""" unittest.main() if __name__ == "__main__": main()