graphiti/tests/cross_encoder/test_bge_reranker_client_int.py
Daniel Chalef 8a6b72a909 Separate unit and integration tests to allow external contributors
This change addresses the issue where external contributor PRs fail unit
tests because GitHub secrets (API keys) are unavailable to external PRs
for security reasons.

Changes:
- Split GitHub Actions workflow into two jobs:
  - unit-tests: Runs without API keys or database connections (all PRs)
  - integration-tests: Runs only for internal contributors with API keys
- Renamed test_bge_reranker_client.py to test_bge_reranker_client_int.py
  to follow naming convention for integration tests
- Unit tests now skip all tests requiring databases or API keys
- Integration tests properly separated into:
  - Database integration tests (no API keys)
  - API integration tests (requires OPENAI_API_KEY, etc.)

The unit-tests job now:
- Runs for all PRs (internal and external)
- Requires no GitHub secrets
- Disables all database drivers
- Excludes all integration test files
- Passes 93 tests successfully

The integration-tests job:
- Only runs for internal contributors (same repo PRs or pushes to main)
- Has access to GitHub secrets
- Tests database operations and API integrations
- Uses conditional: github.event.pull_request.head.repo.full_name == github.repository

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 16:43:29 -07:00

83 lines
2.5 KiB
Python

"""
Copyright 2024, Zep Software, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import pytest
from graphiti_core.cross_encoder.bge_reranker_client import BGERerankerClient
pytestmark = pytest.mark.integration
@pytest.fixture
def client():
return BGERerankerClient()
@pytest.mark.asyncio
@pytest.mark.integration
async def test_rank_basic_functionality(client):
query = 'What is the capital of France?'
passages = [
'Paris is the capital and most populous city of France.',
'London is the capital city of England and the United Kingdom.',
'Berlin is the capital and largest city of Germany.',
]
ranked_passages = await client.rank(query, passages)
# Check if the output is a list of tuples
assert isinstance(ranked_passages, list)
assert all(isinstance(item, tuple) for item in ranked_passages)
# Check if the output has the correct length
assert len(ranked_passages) == len(passages)
# Check if the scores are floats and passages are strings
for passage, score in ranked_passages:
assert isinstance(passage, str)
assert isinstance(score, float)
# Check if the results are sorted in descending order
scores = [score for _, score in ranked_passages]
assert scores == sorted(scores, reverse=True)
@pytest.mark.asyncio
@pytest.mark.integration
async def test_rank_empty_input(client):
query = 'Empty test'
passages = []
ranked_passages = await client.rank(query, passages)
# Check if the output is an empty list
assert ranked_passages == []
@pytest.mark.asyncio
@pytest.mark.integration
async def test_rank_single_passage(client):
query = 'Test query'
passages = ['Single test passage']
ranked_passages = await client.rank(query, passages)
# Check if the output has one item
assert len(ranked_passages) == 1
# Check if the passage is correct and the score is a float
assert ranked_passages[0][0] == passages[0]
assert isinstance(ranked_passages[0][1], float)