TasmotaManager/test_template_matching.py

239 lines
8.7 KiB
Python

#!/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()