tests and actions
This commit is contained in:
parent
c05feb37d3
commit
78f52ea7f4
17 changed files with 4140 additions and 3 deletions
296
.forgejo/workflows/pr-pricing-validation.yml
Normal file
296
.forgejo/workflows/pr-pricing-validation.yml
Normal file
|
@ -0,0 +1,296 @@
|
|||
name: PR Pricing Validation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths:
|
||||
- "hub/services/models/pricing.py"
|
||||
- "hub/services/tests/test_pricing*.py"
|
||||
- "hub/services/views/**"
|
||||
- "hub/services/forms.py"
|
||||
- "hub/services/admin/**"
|
||||
|
||||
jobs:
|
||||
pricing-validation:
|
||||
name: Validate Pricing Changes
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout PR branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.13"
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
enable-cache: true
|
||||
cache-dependency-glob: "uv.lock"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
uv sync --extra dev
|
||||
|
||||
- name: Check for pricing model migrations
|
||||
run: |
|
||||
echo "::group::Checking for required database migrations"
|
||||
|
||||
# Check if pricing models were changed
|
||||
if git diff --name-only origin/main...HEAD | grep -q "hub/services/models/pricing.py"; then
|
||||
echo "📝 Pricing models were modified, checking for migrations..."
|
||||
|
||||
# Check if there are new migration files
|
||||
if git diff --name-only origin/main...HEAD | grep -q "hub/services/migrations/"; then
|
||||
echo "✅ Found migration files in the PR"
|
||||
git diff --name-only origin/main...HEAD | grep "hub/services/migrations/" | head -5
|
||||
else
|
||||
echo "⚠️ Pricing models were changed but no migrations found"
|
||||
echo "Please run: uv run --extra dev manage.py makemigrations"
|
||||
echo "This will be treated as a warning, not a failure"
|
||||
fi
|
||||
else
|
||||
echo "ℹ️ No pricing model changes detected"
|
||||
fi
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Run pricing tests with coverage
|
||||
env:
|
||||
DJANGO_SETTINGS_MODULE: hub.settings
|
||||
run: |
|
||||
echo "::group::Running pricing tests with coverage tracking"
|
||||
|
||||
# Run tests with coverage
|
||||
uv run coverage run --source='hub/services/models/pricing,hub/services/views' \
|
||||
manage.py test \
|
||||
hub.services.tests.test_pricing \
|
||||
hub.services.tests.test_pricing_edge_cases \
|
||||
hub.services.tests.test_pricing_integration \
|
||||
--verbosity=2
|
||||
|
||||
# Generate coverage report
|
||||
uv run coverage report --show-missing --fail-under=85
|
||||
|
||||
# Generate HTML coverage report
|
||||
uv run coverage html
|
||||
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Upload coverage report
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pr-pricing-coverage
|
||||
path: htmlcov/
|
||||
retention-days: 7
|
||||
|
||||
- name: Detect pricing calculation changes
|
||||
run: |
|
||||
echo "::group::Analyzing pricing calculation changes"
|
||||
|
||||
# Check if critical pricing methods were modified
|
||||
CRITICAL_METHODS=(
|
||||
"calculate_discount"
|
||||
"calculate_final_price"
|
||||
"get_price"
|
||||
"get_unit_rate"
|
||||
"get_base_fee"
|
||||
)
|
||||
|
||||
echo "🔍 Checking for changes to critical pricing methods..."
|
||||
|
||||
changed_methods=()
|
||||
for method in "${CRITICAL_METHODS[@]}"; do
|
||||
if git diff origin/main...HEAD -- hub/services/models/pricing.py | grep -q "def $method"; then
|
||||
changed_methods+=("$method")
|
||||
echo "⚠️ Critical method '$method' was modified"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#changed_methods[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo "🚨 CRITICAL PRICING METHODS CHANGED:"
|
||||
printf ' - %s\n' "${changed_methods[@]}"
|
||||
echo ""
|
||||
echo "📋 Extra validation required:"
|
||||
echo " 1. All pricing tests must pass"
|
||||
echo " 2. Manual testing of price calculations recommended"
|
||||
echo " 3. Consider adding regression tests for specific scenarios"
|
||||
echo ""
|
||||
echo "This will not fail the build but requires careful review."
|
||||
else
|
||||
echo "✅ No critical pricing methods were modified"
|
||||
fi
|
||||
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Validate test additions
|
||||
run: |
|
||||
echo "::group::Validating test additions for pricing changes"
|
||||
|
||||
# Check if new pricing features have corresponding tests
|
||||
python3 << 'EOF'
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
def get_git_diff():
|
||||
result = subprocess.run(
|
||||
['git', 'diff', 'origin/main...HEAD', '--', 'hub/services/models/pricing.py'],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
return result.stdout
|
||||
|
||||
def get_test_diff():
|
||||
result = subprocess.run(
|
||||
['git', 'diff', 'origin/main...HEAD', '--', 'hub/services/tests/test_pricing*.py'],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
return result.stdout
|
||||
|
||||
pricing_diff = get_git_diff()
|
||||
test_diff = get_test_diff()
|
||||
|
||||
# Look for new methods in pricing models
|
||||
new_methods = re.findall(r'^\+\s*def\s+(\w+)', pricing_diff, re.MULTILINE)
|
||||
new_classes = re.findall(r'^\+class\s+(\w+)', pricing_diff, re.MULTILINE)
|
||||
|
||||
# Look for new test methods
|
||||
new_test_methods = re.findall(r'^\+\s*def\s+(test_\w+)', test_diff, re.MULTILINE)
|
||||
|
||||
print("📊 Analysis of pricing changes:")
|
||||
if new_classes:
|
||||
print(f" New classes: {', '.join(new_classes)}")
|
||||
if new_methods:
|
||||
print(f" New methods: {', '.join(new_methods)}")
|
||||
if new_test_methods:
|
||||
print(f" New test methods: {', '.join(new_test_methods)}")
|
||||
|
||||
if (new_classes or new_methods) and not new_test_methods:
|
||||
print("⚠️ New pricing functionality detected but no new tests found")
|
||||
print(" Consider adding tests for new features")
|
||||
elif new_test_methods:
|
||||
print("✅ New tests found alongside pricing changes")
|
||||
else:
|
||||
print("ℹ️ No new pricing functionality detected")
|
||||
EOF
|
||||
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Run backward compatibility check
|
||||
env:
|
||||
DJANGO_SETTINGS_MODULE: hub.settings
|
||||
run: |
|
||||
echo "::group::Checking backward compatibility of pricing changes"
|
||||
|
||||
# Create a simple backward compatibility test
|
||||
cat << 'EOF' > check_compatibility.py
|
||||
import os
|
||||
import django
|
||||
from decimal import Decimal
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hub.settings')
|
||||
django.setup()
|
||||
|
||||
from hub.services.models.base import Currency, Term
|
||||
from hub.services.models.providers import CloudProvider
|
||||
from hub.services.models.services import Service
|
||||
from hub.services.models.pricing import VSHNAppCatPrice, VSHNAppCatBaseFee, VSHNAppCatUnitRate
|
||||
|
||||
print("🔄 Testing backward compatibility of pricing API...")
|
||||
|
||||
try:
|
||||
# Test basic model creation (should work with existing API)
|
||||
provider = CloudProvider.objects.create(
|
||||
name="BC Test", slug="bc-test", description="Test", website="https://test.com"
|
||||
)
|
||||
service = Service.objects.create(
|
||||
name="BC Service", slug="bc-service", description="Test", features="Test"
|
||||
)
|
||||
|
||||
price_config = VSHNAppCatPrice.objects.create(
|
||||
service=service,
|
||||
variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
|
||||
term=Term.MTH
|
||||
)
|
||||
|
||||
VSHNAppCatBaseFee.objects.create(
|
||||
vshn_appcat_price_config=price_config,
|
||||
currency=Currency.CHF,
|
||||
amount=Decimal('50.00')
|
||||
)
|
||||
|
||||
VSHNAppCatUnitRate.objects.create(
|
||||
vshn_appcat_price_config=price_config,
|
||||
currency=Currency.CHF,
|
||||
service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
|
||||
amount=Decimal('5.0000')
|
||||
)
|
||||
|
||||
# Test basic price calculation
|
||||
result = price_config.calculate_final_price(Currency.CHF, 'GA', 4)
|
||||
|
||||
if result and 'total_price' in result:
|
||||
print(f"✅ Basic price calculation works: {result['total_price']} CHF")
|
||||
else:
|
||||
print("❌ Price calculation API may have changed")
|
||||
exit(1)
|
||||
|
||||
# Test price retrieval methods
|
||||
base_fee = price_config.get_base_fee(Currency.CHF)
|
||||
unit_rate = price_config.get_unit_rate(Currency.CHF, 'GA')
|
||||
|
||||
if base_fee and unit_rate:
|
||||
print("✅ Price retrieval methods work correctly")
|
||||
else:
|
||||
print("❌ Price retrieval API may have changed")
|
||||
exit(1)
|
||||
|
||||
print("🎉 Backward compatibility check passed!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Backward compatibility issue detected: {e}")
|
||||
exit(1)
|
||||
EOF
|
||||
|
||||
uv run python check_compatibility.py
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Generate pricing test summary
|
||||
if: always()
|
||||
run: |
|
||||
echo "::group::Pricing Test Summary"
|
||||
|
||||
echo "## 🧮 Pricing Test Results" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Count test files and methods
|
||||
total_test_files=$(find hub/services/tests -name "test_pricing*.py" | wc -l)
|
||||
total_test_methods=$(grep -r "def test_" hub/services/tests/test_pricing*.py | wc -l)
|
||||
|
||||
echo "- **Test Files**: $total_test_files pricing-specific test files" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Test Methods**: $total_test_methods individual test methods" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Check if any pricing files were changed
|
||||
if git diff --name-only origin/main...HEAD | grep -q "pricing"; then
|
||||
echo "### 📝 Pricing-Related Changes Detected" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "The following pricing-related files were modified:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
git diff --name-only origin/main...HEAD | grep "pricing" | sed 's/^/- /' >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ All pricing tests have been executed to validate these changes." >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "### ℹ️ No Pricing Changes" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "No pricing-related files were modified in this PR." >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "---" >> $GITHUB_STEP_SUMMARY
|
||||
echo "*Pricing validation completed at $(date)*" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
echo "::endgroup::"
|
Loading…
Add table
Add a link
Reference in a new issue