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
47 changes: 46 additions & 1 deletion tests/integration/conftest.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
"""Shared fixtures for integration tests."""

from pathlib import Path

from typing import Generator

import pytest
from fastapi import Request

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session
from sqlalchemy.engine import Engine

from authentication.noop import NoopAuthDependency
from authentication.interface import AuthTuple

from configuration import configuration
from models.database.base import Base

Expand Down Expand Up @@ -45,6 +50,23 @@ def test_config_fixture() -> Generator:
# Note: Cleanup is handled by the autouse reset_configuration_state fixture


@pytest.fixture(name="current_config", scope="function")
def current_config_fixture() -> Generator:
"""Load current configuration for integration tests.

This fixture loads the actual configuration file from project root (current configuration),
demonstrating integration with the configuration system.
"""
config_path = Path(__file__).parent.parent.parent / "lightspeed-stack.yaml"
assert config_path.exists(), f"Config file not found: {config_path}"

# Load configuration
configuration.load_configuration(str(config_path))

yield configuration
# Note: Cleanup is handled by the autouse reset_configuration_state fixture


@pytest.fixture(name="test_db_engine", scope="function")
def test_db_engine_fixture() -> Generator:
"""Create an in-memory SQLite database engine for testing.
Expand Down Expand Up @@ -81,3 +103,26 @@ def test_db_session_fixture(test_db_engine: Engine) -> Generator[Session, None,
yield session

session.close()


@pytest.fixture(name="test_request")
def test_request_fixture() -> Request:
"""Create a test FastAPI Request object with proper scope."""
return Request(
scope={
"type": "http",
"query_string": b"",
"headers": [],
}
)


@pytest.fixture(name="test_auth")
async def test_auth_fixture(test_request: Request) -> AuthTuple:
"""Create authentication using real noop auth module.

This uses the actual NoopAuthDependency instead of mocking,
making this a true integration test.
"""
noop_auth = NoopAuthDependency()
return await noop_auth(test_request)
84 changes: 84 additions & 0 deletions tests/integration/endpoints/test_config_integration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""Integration tests for the /config endpoint."""

import pytest

from fastapi import Request

from authentication.interface import AuthTuple

from configuration import AppConfig, LogicError
from app.endpoints.config import config_endpoint_handler


@pytest.mark.asyncio
async def test_config_endpoint_returns_config(
test_config: AppConfig,
test_request: Request,
test_auth: AuthTuple,
) -> None:
"""Test that config endpoint returns test configuration.

This integration test verifies:
- Endpoint handler integrates with configuration system
- Configuration values are correctly accessed
- Real noop authentication is used
- Response structure matches expected format

Args:
test_config: Loads test configuration
test_request: FastAPI request
test_auth: noop authentication tuple
"""
response = await config_endpoint_handler(auth=test_auth, request=test_request)

# Verify that response matches the real configuration
assert response == test_config.configuration


@pytest.mark.asyncio
async def test_config_endpoint_returns_current_config(
current_config: AppConfig,
test_request: Request,
test_auth: AuthTuple,
) -> None:
"""Test that config endpoint returns current configuration (from root).

This integration test verifies:
- Endpoint handler integrates with configuration system
- Configuration values are correctly accessed
- Real noop authentication is used
- Response structure matches expected format

Args:
current_config: Loads root configuration
test_request: FastAPI request
test_auth: noop authentication tuple
"""
response = await config_endpoint_handler(auth=test_auth, request=test_request)

# Verify that response matches the root configuration
assert response == current_config.configuration


@pytest.mark.asyncio
async def test_config_endpoint_fails_without_configuration(
test_request: Request,
test_auth: AuthTuple,
) -> None:
"""Test that authorization fails when configuration is not loaded.

This integration test verifies:
- LogicError is raised when configuration is not loaded
- Error message indicates configuration is not loaded

Args:
test_request: FastAPI request
test_auth: noop authentication tuple
"""

# Verify that LogicError is raised when authorization tries to access config
with pytest.raises(LogicError) as exc_info:
await config_endpoint_handler(auth=test_auth, request=test_request)

# Verify error message
assert "configuration is not loaded" in str(exc_info.value)
31 changes: 4 additions & 27 deletions tests/integration/endpoints/test_info_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
from fastapi import HTTPException, Request, status
from llama_stack_client import APIConnectionError
from llama_stack_client.types import VersionInfo
from authentication.interface import AuthTuple

from configuration import AppConfig
from app.endpoints.info import info_endpoint_handler
from authentication.noop import NoopAuthDependency
from version import __version__


Expand All @@ -36,35 +36,12 @@ def mock_llama_stack_client_fixture(
yield mock_client


@pytest.fixture(name="test_request")
def test_request_fixture() -> Request:
"""Create a test FastAPI Request object with proper scope."""
return Request(
scope={
"type": "http",
"query_string": b"",
"headers": [],
}
)


@pytest.fixture(name="test_auth")
async def test_auth_fixture(test_request: Request) -> tuple[str, str, bool, str]:
"""Create authentication using real noop auth module.

This uses the actual NoopAuthDependency instead of mocking,
making this a true integration test.
"""
noop_auth = NoopAuthDependency()
return await noop_auth(test_request)


@pytest.mark.asyncio
async def test_info_endpoint_returns_service_information(
test_config: AppConfig,
mock_llama_stack_client: AsyncMockType,
test_request: Request,
test_auth: tuple[str, str, bool, str],
test_auth: AuthTuple,
) -> None:
"""Test that info endpoint returns correct service information.

Expand Down Expand Up @@ -100,7 +77,7 @@ async def test_info_endpoint_handles_connection_error(
test_config: AppConfig,
mock_llama_stack_client: AsyncMockType,
test_request: Request,
test_auth: tuple[str, str, bool, str],
test_auth: AuthTuple,
mocker: MockerFixture,
) -> None:
"""Test that info endpoint properly handles Llama Stack connection errors.
Expand Down Expand Up @@ -140,7 +117,7 @@ async def test_info_endpoint_uses_configuration_values(
test_config: AppConfig,
mock_llama_stack_client: AsyncMockType,
test_request: Request,
test_auth: tuple[str, str, bool, str],
test_auth: AuthTuple,
) -> None:
"""Test that info endpoint correctly uses configuration values.

Expand Down
Loading