mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-27 21:05:34 +00:00
test: add live marker, CI coverage gate, rust bridge boundary tests (#256)
This commit is contained in:
@@ -63,7 +63,20 @@ jobs:
|
||||
run: uv run maturin develop --manifest-path rust/crates/openjarvis-python/Cargo.toml
|
||||
|
||||
- name: Run tests
|
||||
run: uv run pytest tests/ -v --tb=short -m "not live and not cloud"
|
||||
run: |
|
||||
uv run pytest tests/ -v --tb=short -m "not live and not cloud" \
|
||||
--cov=openjarvis \
|
||||
--cov-report=term-missing \
|
||||
--cov-report=xml \
|
||||
--cov-fail-under=60
|
||||
|
||||
- name: Upload coverage report
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-xml
|
||||
path: coverage.xml
|
||||
if-no-files-found: warn
|
||||
|
||||
rust:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -9,6 +9,8 @@ from __future__ import annotations
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from openjarvis.connectors.obsidian import ObsidianConnector
|
||||
from openjarvis.connectors.pipeline import IngestionPipeline
|
||||
from openjarvis.connectors.store import KnowledgeStore
|
||||
@@ -19,6 +21,7 @@ from openjarvis.tools.knowledge_search import KnowledgeSearchTool
|
||||
DOCS_DIR = Path(__file__).resolve().parents[2] / "docs"
|
||||
|
||||
|
||||
@pytest.mark.live
|
||||
def test_live_obsidian_full_pipeline() -> None:
|
||||
"""Smoke test: index real .md files, then search them."""
|
||||
assert DOCS_DIR.is_dir(), f"Docs dir not found: {DOCS_DIR}"
|
||||
|
||||
@@ -4,6 +4,8 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
class TestGetRustModule:
|
||||
"""Test get_rust_module() returns the Rust extension module."""
|
||||
@@ -127,6 +129,122 @@ class TestRetrievalResultsFromJson:
|
||||
assert results[0].metadata == {"nested": True}
|
||||
|
||||
|
||||
class TestConverterInvalidInputs:
|
||||
"""Boundary behavior: malformed JSON and missing/unexpected fields."""
|
||||
|
||||
def test_scan_result_malformed_json_raises(self):
|
||||
from openjarvis._rust_bridge import scan_result_from_json
|
||||
|
||||
with pytest.raises(json.JSONDecodeError):
|
||||
scan_result_from_json("{not json")
|
||||
|
||||
def test_scan_result_missing_findings_key_is_clean(self):
|
||||
from openjarvis._rust_bridge import scan_result_from_json
|
||||
|
||||
result = scan_result_from_json("{}")
|
||||
assert result.clean
|
||||
assert result.findings == []
|
||||
|
||||
def test_scan_result_unknown_threat_level_raises(self):
|
||||
from openjarvis._rust_bridge import scan_result_from_json
|
||||
|
||||
data = {
|
||||
"findings": [
|
||||
{
|
||||
"pattern_name": "x",
|
||||
"matched_text": "y",
|
||||
"threat_level": "not-a-level",
|
||||
"start": 0,
|
||||
"end": 1,
|
||||
"description": "",
|
||||
},
|
||||
],
|
||||
}
|
||||
with pytest.raises(ValueError):
|
||||
scan_result_from_json(json.dumps(data))
|
||||
|
||||
def test_scan_result_finding_missing_fields_uses_defaults(self):
|
||||
from openjarvis._rust_bridge import scan_result_from_json
|
||||
|
||||
result = scan_result_from_json('{"findings": [{}]}')
|
||||
assert not result.clean
|
||||
finding = result.findings[0]
|
||||
assert finding.pattern_name == ""
|
||||
assert finding.matched_text == ""
|
||||
assert finding.threat_level.value == "low"
|
||||
assert finding.start == 0
|
||||
assert finding.end == 0
|
||||
|
||||
def test_injection_result_malformed_json_raises(self):
|
||||
from openjarvis._rust_bridge import injection_result_from_json
|
||||
|
||||
with pytest.raises(json.JSONDecodeError):
|
||||
injection_result_from_json("")
|
||||
|
||||
def test_injection_result_unknown_top_level_threat_defaults_to_low(self):
|
||||
from openjarvis._rust_bridge import injection_result_from_json
|
||||
|
||||
data = {
|
||||
"is_clean": True,
|
||||
"findings": [],
|
||||
"threat_level": "bogus",
|
||||
}
|
||||
result = injection_result_from_json(json.dumps(data))
|
||||
assert result.threat_level.value == "low"
|
||||
|
||||
def test_injection_result_missing_keys_uses_defaults(self):
|
||||
from openjarvis._rust_bridge import injection_result_from_json
|
||||
|
||||
result = injection_result_from_json("{}")
|
||||
assert result.is_clean is True
|
||||
assert result.findings == []
|
||||
assert result.threat_level.value == "low"
|
||||
|
||||
def test_retrieval_results_malformed_json_raises(self):
|
||||
from openjarvis._rust_bridge import retrieval_results_from_json
|
||||
|
||||
with pytest.raises(json.JSONDecodeError):
|
||||
retrieval_results_from_json("not-json")
|
||||
|
||||
def test_retrieval_results_metadata_invalid_json_string_falls_back_to_empty(self):
|
||||
from openjarvis._rust_bridge import retrieval_results_from_json
|
||||
|
||||
data = [
|
||||
{
|
||||
"content": "c",
|
||||
"score": 0.1,
|
||||
"source": "s",
|
||||
"metadata": "{not valid json",
|
||||
},
|
||||
]
|
||||
results = retrieval_results_from_json(json.dumps(data))
|
||||
assert results[0].metadata == {}
|
||||
|
||||
def test_retrieval_results_missing_fields_uses_defaults(self):
|
||||
from openjarvis._rust_bridge import retrieval_results_from_json
|
||||
|
||||
results = retrieval_results_from_json("[{}]")
|
||||
assert len(results) == 1
|
||||
assert results[0].content == ""
|
||||
assert results[0].score == 0.0
|
||||
assert results[0].source == ""
|
||||
assert results[0].metadata == {}
|
||||
|
||||
def test_retrieval_results_score_string_coerced_to_float(self):
|
||||
from openjarvis._rust_bridge import retrieval_results_from_json
|
||||
|
||||
data = [{"content": "x", "score": "2.5", "source": "", "metadata": {}}]
|
||||
results = retrieval_results_from_json(json.dumps(data))
|
||||
assert results[0].score == 2.5
|
||||
|
||||
def test_retrieval_results_non_iterable_top_level_raises(self):
|
||||
from openjarvis._rust_bridge import retrieval_results_from_json
|
||||
|
||||
# Top-level must be a list; a bare number has no iteration.
|
||||
with pytest.raises(TypeError):
|
||||
retrieval_results_from_json("42")
|
||||
|
||||
|
||||
class TestRustBackedModules:
|
||||
"""Test that Rust-backed modules work correctly."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user