Add semantic-index service, deployment assets, and tests
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from semantic_index.app import create_app
|
||||
from semantic_index.config import Settings
|
||||
from semantic_index.models import SearchResult
|
||||
|
||||
|
||||
class FakeSearchService:
|
||||
def search(self, query):
|
||||
return [
|
||||
SearchResult(
|
||||
id="redmine:issue:1:chunk:0",
|
||||
score=0.8,
|
||||
text="Snippet text",
|
||||
payload={
|
||||
"source": "redmine",
|
||||
"project_identifier": "customer-service",
|
||||
"doc_type": "issue",
|
||||
"issue_id": 1,
|
||||
"redmine_url": "http://redmine/issues/1",
|
||||
"source_record_id": "issue:1",
|
||||
},
|
||||
)
|
||||
]
|
||||
|
||||
def get_document(self, document_id):
|
||||
return {"id": document_id, "text": "Full text", "payload": {}}
|
||||
|
||||
|
||||
class FakeStore:
|
||||
def list_projects(self, source=None, limit=1000):
|
||||
return [{"project_identifier": "customer-service", "document_count": 10}]
|
||||
|
||||
|
||||
class FakeRefreshService:
|
||||
def __init__(self):
|
||||
self.calls = []
|
||||
|
||||
def refresh_redmine_project_limits(self, project_limits, dry_run=False, force_rebuild=False, overlap_minutes=15):
|
||||
self.calls.append((project_limits, dry_run, force_rebuild, overlap_minutes))
|
||||
return {"source": "redmine", "projects": len(project_limits), "dry_run": dry_run}
|
||||
|
||||
|
||||
def fake_services():
|
||||
refresh = FakeRefreshService()
|
||||
return {
|
||||
"settings": Settings(
|
||||
openai_api_key="",
|
||||
qdrant_url="http://qdrant",
|
||||
qdrant_api_key=None,
|
||||
qdrant_collection="semantic",
|
||||
redmine_url="http://redmine",
|
||||
redmine_api_key="",
|
||||
redmine_project_identifier=None,
|
||||
sample_limit=50,
|
||||
bind_host="127.0.0.1",
|
||||
bind_port=8787,
|
||||
service_api_key=None,
|
||||
refresh_state_path=Path(".cache/semantic_index/refresh_state.json"),
|
||||
),
|
||||
"search": FakeSearchService(),
|
||||
"store": FakeStore(),
|
||||
"refresh": refresh,
|
||||
}
|
||||
|
||||
|
||||
class SemanticIndexAppTest(unittest.TestCase):
|
||||
def test_health_does_not_build_live_services(self):
|
||||
def broken_builder():
|
||||
raise AssertionError("health should not build live clients")
|
||||
|
||||
app = create_app(service_builder=broken_builder)
|
||||
routes = {route.path: route.endpoint for route in app.routes}
|
||||
|
||||
self.assertEqual({"status": "ok"}, routes["/health"]())
|
||||
|
||||
def test_search_endpoint_returns_normalized_agent_response(self):
|
||||
app = create_app(service_builder=fake_services)
|
||||
routes = {route.path: route.endpoint for route in app.routes}
|
||||
|
||||
response = routes["/search"]({"query": "printer", "project_identifier": "customer-service", "limit": 3})
|
||||
|
||||
self.assertEqual("printer", response["query"])
|
||||
self.assertEqual("customer-service", response["filters"]["project_identifier"])
|
||||
self.assertEqual("customer-service", response["results"][0]["citation"]["project_identifier"])
|
||||
|
||||
def test_projects_endpoint_lists_indexed_projects(self):
|
||||
app = create_app(service_builder=fake_services)
|
||||
routes = {route.path: route.endpoint for route in app.routes}
|
||||
|
||||
response = routes["/projects"]()
|
||||
|
||||
self.assertEqual("customer-service", response["projects"][0]["project_identifier"])
|
||||
|
||||
def test_refresh_endpoint_passes_project_limits_and_cost_flags(self):
|
||||
services = fake_services()
|
||||
app = create_app(service_builder=lambda: services)
|
||||
routes = {route.path: route.endpoint for route in app.routes}
|
||||
|
||||
response = routes["/sources/redmine/refresh"](
|
||||
{
|
||||
"project_limits": {"customer-service": 5},
|
||||
"dry_run": True,
|
||||
"force_rebuild": False,
|
||||
"overlap_minutes": 30,
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(response["dry_run"])
|
||||
self.assertEqual(({"customer-service": 5}, True, False, 30), services["refresh"].calls[0])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user