""" Comprehensive tests for version differentiation in the Blender text texture generator addon. Tests the quadruple-layer detection system: 1. Template-generated constants (VERSION_TYPE, is_free_version(), ENABLED_FEATURES) 2. Runtime import detection flags (PRESETS_AVAILABLE, UTILITY_OPERATORS_AVAILABLE) 3. Version limits (get_version_limits() returns correct values) 4. UI helper functions (version display and feature gating) """ import pytest import sys from unittest.mock import Mock, patch, MagicMock from types import ModuleType class TestVersionDetection: """Test suite for version detection methods.""" def test_version_type_constant(self): """Test VERSION_TYPE constant is properly set.""" from src.utils.constants import VERSION_TYPE assert VERSION_TYPE in ["free", "full"], f"VERSION_TYPE should be 'free' or 'full', got '{VERSION_TYPE}'" def test_is_free_version_function(self): """Test is_free_version() function returns correct boolean.""" from src.utils.constants import is_free_version, VERSION_TYPE result = is_free_version() assert isinstance(result, bool), "is_free_version() should return a boolean" # Result should match VERSION_TYPE expected = VERSION_TYPE == "free" assert result == expected, f"is_free_version() returned {result}, expected {expected} based on VERSION_TYPE='{VERSION_TYPE}'" def test_is_full_version_function(self): """Test is_full_version() function returns correct boolean.""" from src.utils.constants import is_full_version, VERSION_TYPE result = is_full_version() assert isinstance(result, bool), "is_full_version() should return a boolean" # Result should match VERSION_TYPE expected = VERSION_TYPE == "full" assert result == expected, f"is_full_version() returned {result}, expected {expected} based on VERSION_TYPE='{VERSION_TYPE}'" def test_enabled_features_list(self): """Test ENABLED_FEATURES contains appropriate features for version.""" from src.utils.constants import ENABLED_FEATURES, VERSION_TYPE assert isinstance(ENABLED_FEATURES, list), "ENABLED_FEATURES should be a list" assert len(ENABLED_FEATURES) > 0, "ENABLED_FEATURES should not be empty" # Basic features should always be present assert "basic" in ENABLED_FEATURES, "Basic features should always be enabled" assert "preview" in ENABLED_FEATURES, "Preview features should always be enabled" if VERSION_TYPE == "free": # Free version should have limited features - only basic and preview expected_free_features = ["basic", "preview"] for feature in ENABLED_FEATURES: assert feature in expected_free_features, f"Free version should only have basic features, found '{feature}'" else: # Full version should have additional features beyond basic and preview assert len(ENABLED_FEATURES) > 2, "Full version should have more than just basic and preview features" def test_get_version_limits_function(self): """Test get_version_limits() returns correct technical limits.""" from src.utils.constants import get_version_limits, VERSION_TYPE limits = get_version_limits() assert isinstance(limits, dict), "get_version_limits() should return a dictionary" # Check required keys required_keys = ["max_texture_size", "max_concurrent_operations"] for key in required_keys: assert key in limits, f"Missing required key '{key}' in version limits" # Check value types assert isinstance(limits["max_texture_size"], int), "max_texture_size should be an integer" assert isinstance(limits["max_concurrent_operations"], int), "max_concurrent_operations should be an integer" # Check version-specific limits if VERSION_TYPE == "free": assert limits["max_texture_size"] == 1024, f"Free version should have 1024px limit, got {limits['max_texture_size']}" assert limits["max_concurrent_operations"] == 1, f"Free version should have 1 concurrent operation, got {limits['max_concurrent_operations']}" else: assert limits["max_texture_size"] == 4096, f"Full version should have 4096px limit, got {limits['max_texture_size']}" assert limits["max_concurrent_operations"] == 4, f"Full version should have 4 concurrent operations, got {limits['max_concurrent_operations']}" def test_get_version_limits_full_returns_pro_limits(self): """Verify full version returns correct limits for texture size and concurrent operations.""" from src.utils.constants import get_version_limits from unittest.mock import patch with patch('src.utils.constants.VERSION_TYPE', 'full'): limits = get_version_limits() assert limits["max_texture_size"] == 4096, \ f"Expected full version max_texture_size=4096, got {limits['max_texture_size']}" assert limits["max_concurrent_operations"] == 4, \ f"Expected full version max_concurrent_operations=4, got {limits['max_concurrent_operations']}" def test_get_version_limits_free_returns_restricted_limits(self): """Verify free version returns restricted limits for texture size and concurrent operations.""" from src.utils.constants import get_version_limits from unittest.mock import patch with patch('src.utils.constants.VERSION_TYPE', 'free'): limits = get_version_limits() assert limits["max_texture_size"] == 1024, \ f"Expected free version max_texture_size=1024, got {limits['max_texture_size']}" assert limits["max_concurrent_operations"] == 1, \ f"Expected free version max_concurrent_operations=1, got {limits['max_concurrent_operations']}" class TestRuntimeImportDetection: """Test suite for runtime import detection flags.""" def test_presets_available_flag(self): """Test PRESETS_AVAILABLE flag is properly set based on import success.""" from src import PRESETS_AVAILABLE assert isinstance(PRESETS_AVAILABLE, bool), "PRESETS_AVAILABLE should be a boolean" def test_utility_operators_available_flag(self): """Test UTILITY_OPERATORS_AVAILABLE flag is properly set based on import success.""" from src import UTILITY_OPERATORS_AVAILABLE assert isinstance(UTILITY_OPERATORS_AVAILABLE, bool), "UTILITY_OPERATORS_AVAILABLE should be a boolean" class TestFeatureAvailability: """Test suite for feature availability and gating.""" def test_feature_gating_based_on_version(self): """Test that features are properly gated based on version type.""" from src.utils.constants import is_free_version, ENABLED_FEATURES if is_free_version(): # Free version should only have basic and preview features expected_features = ["basic", "preview"] assert set(ENABLED_FEATURES) == set(expected_features), f"Free version should only have {expected_features}" else: # Full version should have more features assert len(ENABLED_FEATURES) > 2, "Full version should have more than just basic features" assert "basic" in ENABLED_FEATURES, "Full version should include basic features" assert "preview" in ENABLED_FEATURES, "Full version should include preview features" def test_runtime_import_detection_flags_exist(self): """Test that runtime import detection flags exist.""" try: from src import PRESETS_AVAILABLE, UTILITY_OPERATORS_AVAILABLE assert isinstance(PRESETS_AVAILABLE, bool), "PRESETS_AVAILABLE should be a boolean" assert isinstance(UTILITY_OPERATORS_AVAILABLE, bool), "UTILITY_OPERATORS_AVAILABLE should be a boolean" except ImportError as e: pytest.fail(f"Runtime detection flags should be available: {e}") class TestUIComponents: """Test suite for UI component version display.""" def test_get_version_badge_text(self): """Test get_version_badge_text() returns appropriate badge text.""" from src.utils.constants import get_version_badge_text, is_free_version badge_text = get_version_badge_text() assert isinstance(badge_text, str), "get_version_badge_text() should return a string" assert len(badge_text) > 0, "Badge text should not be empty" if is_free_version(): assert "FREE" in badge_text.upper(), "Free version badge should contain 'FREE'" else: assert "PRO" in badge_text.upper() or "FULL" in badge_text.upper(), "Full version badge should contain 'PRO' or 'FULL'" def test_should_show_feature_lock(self): """Test should_show_feature_lock() returns correct values for features.""" from src.utils.constants import should_show_feature_lock, is_free_version # Test premium features from the actual implementation premium_features = ["presets", "utility_operators", "image_overlays", "batch_processing", "advanced_positioning"] for feature in premium_features: result = should_show_feature_lock(feature) assert isinstance(result, bool), f"should_show_feature_lock('{feature}') should return boolean" if is_free_version(): assert result == True, f"Feature lock should be shown for '{feature}' in free version" else: assert result == False, f"Feature lock should not be shown for '{feature}' in full version" def test_get_upgrade_hint_text(self): """Test get_upgrade_hint_text() returns appropriate upgrade messages.""" from src.utils.constants import get_upgrade_hint_text, is_free_version # The function requires a feature_name parameter feature_name = "Test Feature" hint_text = get_upgrade_hint_text(feature_name) assert isinstance(hint_text, str), "get_upgrade_hint_text() should return a string" if is_free_version(): assert len(hint_text) > 0, "Free version should have upgrade hint text" assert feature_name in hint_text, "Upgrade hint should mention the feature name" assert "Pro" in hint_text, "Upgrade hint should mention Pro version" else: assert len(hint_text) == 0, "Full version should have empty upgrade hint text" def test_get_version_info_details(self): """Test get_version_info_details() returns comprehensive version information.""" from src.utils.constants import get_version_info_details, is_free_version, get_version_limits info_details = get_version_info_details() assert isinstance(info_details, dict), "get_version_info_details() should return a dictionary" assert len(info_details) > 0, "Version info details should not be empty" class TestIntegrationScenarios: """Test suite for cross-system integration validation.""" def test_template_and_runtime_consistency(self): """Test that template-generated constants and runtime flags are consistent.""" from src.utils.constants import is_free_version, ENABLED_FEATURES from src import PRESETS_AVAILABLE, UTILITY_OPERATORS_AVAILABLE # In a properly built system, runtime availability should align with template configuration if is_free_version(): # Free version should have limited features in template expected_features = ["basic", "preview"] assert set(ENABLED_FEATURES) == set(expected_features), f"Template should only enable basic features in free version, got {ENABLED_FEATURES}" else: # Full version should have more features enabled in template assert len(ENABLED_FEATURES) > 2, "Template should enable more features in full version" assert "basic" in ENABLED_FEATURES, "Template should enable basic features in full version" assert "preview" in ENABLED_FEATURES, "Template should enable preview features in full version" def test_mock_operators_dont_crash(self): """Test that mock operators are properly implemented and don't crash.""" # This test ensures that when premium features are missing, # the system gracefully handles it with mock implementations # Test that we can import the main module without crashes try: import src assert True, "Main module import should not crash" except Exception as e: pytest.fail(f"Main module import crashed: {e}") # Test that runtime flags are properly set assert hasattr(src, 'PRESETS_AVAILABLE'), "Runtime should set PRESETS_AVAILABLE flag" assert hasattr(src, 'UTILITY_OPERATORS_AVAILABLE'), "Runtime should set UTILITY_OPERATORS_AVAILABLE flag" class TestVersionDifferentiationScenarios: """Test specific free vs full version difference scenarios.""" def test_free_version_complete_scenario(self): """Test complete free version scenario with all restrictions.""" from src.utils.constants import is_free_version, get_version_limits, ENABLED_FEATURES if is_free_version(): # Feature restrictions - free version should only have basic features expected_features = ["basic", "preview"] assert set(ENABLED_FEATURES) == set(expected_features), f"Free version should only have {expected_features}" # Technical limitations limits = get_version_limits() assert limits["max_texture_size"] == 1024, "Should have 1024px texture limit" assert limits["max_concurrent_operations"] == 1, "Should have 1 concurrent operation limit" def test_full_version_complete_scenario(self): """Test complete full version scenario with all features enabled.""" from src.utils.constants import is_free_version, is_full_version, get_version_limits, ENABLED_FEATURES if not is_free_version(): # Version detection assert is_full_version() == True, "Should detect full version" # Full version should have more features than free assert len(ENABLED_FEATURES) > 2, "Full version should have more than just basic features" assert "basic" in ENABLED_FEATURES, "Full version should include basic features" assert "preview" in ENABLED_FEATURES, "Full version should include preview features" # Generous technical limits limits = get_version_limits() assert limits["max_texture_size"] == 4096, "Should have 4096px texture limit" assert limits["max_concurrent_operations"] == 4, "Should have 4 concurrent operations limit"