Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 19 additions & 24 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ on:
push:
branches:
- main
- dev
- demo
- hotfix
- demo-v4
- dev-v4
paths:
- 'src/backend/**/*.py'
- 'src/tests/**/*.py'
Expand All @@ -24,9 +23,8 @@ on:
- synchronize
branches:
- main
- dev
- demo
- hotfix
- demo-v4
- dev-v4
paths:
- 'src/backend/**/*.py'
- 'src/tests/**/*.py'
Expand Down Expand Up @@ -69,25 +67,22 @@ jobs:
- name: Run tests with coverage
if: env.skip_tests == 'false'
run: |
pytest --cov=. --cov-report=term-missing --cov-report=xml \
--ignore=tests/e2e-test/tests \
--ignore=src/backend/tests/test_app.py \
--ignore=src/tests/agents/test_foundry_integration.py \
--ignore=src/tests/mcp_server/test_factory.py \
--ignore=src/tests/mcp_server/test_hr_service.py \
--ignore=src/backend/tests/test_config.py \
--ignore=src/tests/agents/test_human_approval_manager.py \
--ignore=src/backend/tests/test_team_specific_methods.py \
--ignore=src/backend/tests/models/test_messages.py \
--ignore=src/backend/tests/test_otlp_tracing.py \
--ignore=src/backend/tests/auth/test_auth_utils.py
if python -m pytest src/tests/backend/test_app.py --cov=backend --cov-config=.coveragerc -q > /dev/null 2>&1 && \
python -m pytest src/tests/backend --cov=backend --cov-append --cov-report=term --cov-report=xml --cov-config=.coveragerc --ignore=src/tests/backend/test_app.py; then
echo "Tests completed, checking coverage."
if [ -f coverage.xml ]; then
COVERAGE=$(python -c "import xml.etree.ElementTree as ET; tree = ET.parse('coverage.xml'); root = tree.getroot(); print(float(root.attrib.get('line-rate', 0)) * 100)")
echo "Overall coverage: $COVERAGE%"
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "Coverage is below 80%, failing the job."
exit 1
fi
fi
else
echo "No tests found, skipping coverage check."
fi

Comment on lines +70 to 84
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if ...; then ... else "No tests found" logic will treat any pytest failure (including real test failures/import errors) as “no tests found” and not fail the job, because both pytest commands are inside the if condition and the first command silences all output. Consider explicitly handling pytest exit code 5 (no tests collected) and failing on any other non-zero exit; also avoid depending on bc (may be missing) by doing the threshold comparison in Python.

Suggested change
if python -m pytest src/tests/backend/test_app.py --cov=backend --cov-config=.coveragerc -q > /dev/null 2>&1 && \
python -m pytest src/tests/backend --cov=backend --cov-append --cov-report=term --cov-report=xml --cov-config=.coveragerc --ignore=src/tests/backend/test_app.py; then
echo "Tests completed, checking coverage."
if [ -f coverage.xml ]; then
COVERAGE=$(python -c "import xml.etree.ElementTree as ET; tree = ET.parse('coverage.xml'); root = tree.getroot(); print(float(root.attrib.get('line-rate', 0)) * 100)")
echo "Overall coverage: $COVERAGE%"
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "Coverage is below 80%, failing the job."
exit 1
fi
fi
else
echo "No tests found, skipping coverage check."
fi
# Run initial focused test quietly and handle pytest exit codes explicitly.
python -m pytest src/tests/backend/test_app.py --cov=backend --cov-config=.coveragerc -q > /dev/null 2>&1
first_status=$?
if [ "$first_status" -ne 0 ]; then
if [ "$first_status" -eq 5 ]; then
echo "Pytest reported 'no tests collected' in src/tests/backend/test_app.py, skipping coverage check."
exit 0
else
echo "Pytest failed during initial run (src/tests/backend/test_app.py) with exit code $first_status."
exit "$first_status"
fi
fi
# Run the full backend test suite with coverage and handle exit codes.
python -m pytest src/tests/backend --cov=backend --cov-append --cov-report=term --cov-report=xml --cov-config=.coveragerc --ignore=src/tests/backend/test_app.py
second_status=$?
if [ "$second_status" -ne 0 ]; then
if [ "$second_status" -eq 5 ]; then
echo "Pytest reported 'no tests collected' in src/tests/backend, skipping coverage check."
exit 0
else
echo "Pytest failed during main backend test run with exit code $second_status."
exit "$second_status"
fi
fi
echo "Tests completed, checking coverage."
if [ -f coverage.xml ]; then
python - << 'EOF'
import sys
import xml.etree.ElementTree as ET
tree = ET.parse('coverage.xml')
root = tree.getroot()
coverage = float(root.attrib.get('line-rate', 0.0)) * 100.0
print(f"Overall coverage: {coverage}%")
if coverage < 80.0:
print("Coverage is below 80%, failing the job.")
sys.exit(1)
EOF
fi

Copilot uses AI. Check for mistakes.
# - name: Run tests with coverage
# if: env.skip_tests == 'false'
# run: |
# pytest --cov=. --cov-report=term-missing --cov-report=xml --ignore=tests/e2e-test/tests

- name: Skip coverage report if no tests
if: env.skip_tests == 'true'
run: |
echo "Skipping coverage report because no tests were found."
echo "Skipping coverage report because no tests were found."
3 changes: 3 additions & 0 deletions src/tests/backend/auth/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Empty __init__.py file for auth tests package.
"""
63 changes: 63 additions & 0 deletions src/tests/backend/auth/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""
Test configuration for auth module tests.
"""

import pytest
import sys
import os
from unittest.mock import MagicMock, patch
import base64
import json

# Add the backend directory to the Python path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', 'backend'))

@pytest.fixture
def mock_sample_headers():
"""Mock headers with EasyAuth authentication data."""
return {
"x-ms-client-principal-id": "12345678-1234-1234-1234-123456789012",
"x-ms-client-principal-name": "testuser@example.com",
"x-ms-client-principal-idp": "aad",
"x-ms-token-aad-id-token": "sample.jwt.token",
"x-ms-client-principal": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsInRpZCI6IjEyMzQ1Njc4LTEyMzQtMTIzNC0xMjM0LTEyMzQ1Njc4OTAxMiJ9"
}

@pytest.fixture
def mock_empty_headers():
"""Mock headers without authentication data."""
return {
"content-type": "application/json",
"user-agent": "test-agent"
}

@pytest.fixture
def mock_valid_base64_principal():
"""Mock valid base64 encoded principal with tenant ID."""
mock_data = {
"typ": "JWT",
"alg": "RS256",
"tid": "87654321-4321-4321-4321-210987654321",
"oid": "12345678-1234-1234-1234-123456789012",
"preferred_username": "testuser@example.com",
"name": "Test User"
}

json_str = json.dumps(mock_data)
return base64.b64encode(json_str.encode('utf-8')).decode('utf-8')

@pytest.fixture
def mock_invalid_base64_principal():
"""Mock invalid base64 encoded principal."""
return "invalid_base64_string!"

@pytest.fixture
def sample_user_mock():
"""Mock sample_user data for testing."""
return {
"x-ms-client-principal-id": "00000000-0000-0000-0000-000000000000",
"x-ms-client-principal-name": "testusername@contoso.com",
"x-ms-client-principal-idp": "aad",
"x-ms-token-aad-id-token": "your_aad_id_token",
"x-ms-client-principal": "your_base_64_encoded_token"
}
Loading