Skip to content
Closed
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
76 changes: 34 additions & 42 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,42 +1,34 @@
# name: CI Pipeline
# on:
# workflow_dispatch:
# # push:
# # branches:
# # - main

# jobs:
# lint-and-test:
# runs-on: ubuntu-latest

# steps:
# - name: Checkout code
# uses: actions/checkout@v4

# - name: Install uv
# uses: astral-sh/setup-uv@v5

# - name: Set up Python
# uses: actions/setup-python@v5
# with:
# python-version-file: .python-version

# - name: Install dependencies
# run: |
# uv sync --all-groups

# - name: Linting Check
# run: |
# uv run ruff check . --show-fixes

# - name: Auto-format with Ruff
# run: |
# uv run ruff check . --fix --exit-non-zero-on-fix

# - name: Type check with mypy
# run: uv run mypy

# - name: Run tests
# env:
# AWS_REGION: ${{ secrets.AWS_REGION }}
# run: uv run pytest
name: CI Pipeline
on:
push:
branches: [main, feature/*]
pull_request:
branches: [main]

jobs:
lint-and-test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: .python-version

- name: Install dependencies
run: uv sync --all-groups

- name: Linting Check
run: uv run ruff check . --show-fixes

- name: Type check with mypy
run: uv run mypy

- name: Run tests
run: uv run pytest --tb=short
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ lint = [
"ruff>=0.14.0",
]
test = [
"httpx>=0.28.1",
"pytest>=8.4.2",
"pytest-asyncio>=1.2.0",
]
Expand Down
81 changes: 81 additions & 0 deletions tests/unit/test_additional_domain_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""Unit tests for additional domain models."""

from biomedical_graphrag.domain.citation import CitationNetwork
from biomedical_graphrag.domain.dataset import (
GeneDataset,
GeneMetadata,
PaperDataset,
PaperMetadata,
)
from biomedical_graphrag.domain.gene import GeneRecord


class TestGeneRecord:
def test_default_creation(self) -> None:
gene = GeneRecord()
assert gene.gene_id == ""
assert gene.name == ""
assert gene.linked_pmids == []

def test_full_creation(self) -> None:
gene = GeneRecord(
gene_id="672",
name="BRCA1",
description="BRCA1 DNA repair associated",
chromosome="17",
map_location="17q21.31",
organism="Homo sapiens",
aliases="BRCA1/BRCA2-containing complex",
linked_pmids=["12345", "67890"],
)
assert gene.gene_id == "672"
assert gene.name == "BRCA1"
assert len(gene.linked_pmids) == 2


class TestCitationNetwork:
def test_default_creation(self) -> None:
citation = CitationNetwork()
assert citation.pmid == ""
assert citation.cited_by == []
assert citation.references == []

def test_with_data(self) -> None:
citation = CitationNetwork(
pmid="12345",
cited_by=["11111", "22222"],
references=["33333"],
)
assert len(citation.cited_by) == 2
assert len(citation.references) == 1


class TestDatasetModels:
def test_paper_metadata_defaults(self) -> None:
meta = PaperMetadata()
assert meta.total_papers == 0
assert meta.collection_date == ""

def test_paper_dataset_defaults(self) -> None:
ds = PaperDataset()
assert ds.papers == []
assert ds.citation_network == {}

def test_gene_metadata_defaults(self) -> None:
meta = GeneMetadata()
assert meta.total_genes == 0
assert meta.genes_with_pubmed_links == 0

def test_gene_dataset_defaults(self) -> None:
ds = GeneDataset()
assert ds.genes == []

def test_gene_dataset_with_data(self) -> None:
gene = GeneRecord(gene_id="672", name="BRCA1")
ds = GeneDataset(
metadata=GeneMetadata(total_genes=1, genes_with_pubmed_links=1),
genes=[gene],
)
assert ds.metadata.total_genes == 1
assert len(ds.genes) == 1
assert ds.genes[0].name == "BRCA1"
79 changes: 79 additions & 0 deletions tests/unit/test_api_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""Unit tests for FastAPI server endpoints."""

import pytest
from fastapi.testclient import TestClient

from biomedical_graphrag.api.server import (
HealthResponse,
SearchRequest,
SearchResponse,
TraceStep,
app,
)


@pytest.fixture
def client():
"""Create a test client for the FastAPI app."""
return TestClient(app)


class TestHealthEndpoint:
def test_health_check_returns_healthy(self, client: TestClient) -> None:
response = client.get("/health")
assert response.status_code == 200
assert response.json() == {"status": "healthy"}


class TestSearchRequestModel:
def test_default_values(self) -> None:
req = SearchRequest(query="test")
assert req.query == "test"
assert req.limit == 5
assert req.mode == "graphrag"

def test_custom_values(self) -> None:
req = SearchRequest(query="BRCA1", limit=3, mode="dense")
assert req.limit == 3
assert req.mode == "dense"

def test_limit_validation_max(self) -> None:
from pydantic import ValidationError

with pytest.raises(ValidationError):
SearchRequest(query="test", limit=10)

def test_limit_validation_min(self) -> None:
from pydantic import ValidationError

with pytest.raises(ValidationError):
SearchRequest(query="test", limit=0)


class TestResponseModels:
def test_search_response_defaults(self) -> None:
resp = SearchResponse()
assert resp.summary is None
assert resp.results == []
assert resp.trace == []
assert resp.metadata == {}

def test_trace_step_creation(self) -> None:
step = TraceStep(name="qdrant_search", arguments={"query": "test"}, result_count=5)
assert step.name == "qdrant_search"
assert step.arguments == {"query": "test"}
assert step.result_count == 5

def test_health_response(self) -> None:
resp = HealthResponse()
assert resp.status == "healthy"


class TestSearchEndpoint:
def test_search_missing_query(self, client: TestClient) -> None:
response = client.post("/api/graphrag-query", json={})
assert response.status_code == 422

def test_search_invalid_limit(self, client: TestClient) -> None:
response = client.post("/api/graphrag-query", json={"query": "test", "limit": -1})
assert response.status_code == 422
2 changes: 2 additions & 0 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading