300 lines
16 KiB
Python
300 lines
16 KiB
Python
"""
|
|
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']}"
|
|
|
|
def test_has_text_fitting_returns_correct_value_per_version(self):
|
|
"""Test that has_text_fitting() returns correct value based on VERSION_TYPE."""
|
|
from src.utils.constants import has_text_fitting
|
|
from unittest.mock import patch
|
|
|
|
# Test free version - need to patch ENABLED_FEATURES since it's computed at import
|
|
with patch('src.utils.constants.VERSION_TYPE', 'free'), \
|
|
patch('src.utils.constants.ENABLED_FEATURES', ['basic', 'preview']):
|
|
assert has_text_fitting() is False
|
|
|
|
# Test full version - need to patch ENABLED_FEATURES since it's computed at import
|
|
with patch('src.utils.constants.VERSION_TYPE', 'full'), \
|
|
patch('src.utils.constants.ENABLED_FEATURES', ['basic', 'preview', 'text_fitting']):
|
|
assert has_text_fitting() is True
|
|
|
|
|
|
|
|
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" |