Skip to main content
Glama
test_summarization_models.py11.3 kB
"""Unit tests for summarization models. Tests Pydantic models for response compression and chunking. """ import pytest from pydantic import ValidationError from src.models.summarization import ( ChunkMetadata, ContentChunk, DetailsFetchInfo, SummarizationResult, SummarizationStrategy, SummaryMetadata, SummaryResponse, ) class TestDetailsFetchInfo: """Test suite for DetailsFetchInfo model.""" def test_create_details_fetch_info(self): """Test creating DetailsFetchInfo with required fields.""" info = DetailsFetchInfo(endpoint="/api/v1/bookings/123", parameters={"fields": "all"}) assert info.endpoint == "/api/v1/bookings/123" assert info.parameters == {"fields": "all"} def test_details_fetch_info_empty_parameters(self): """Test DetailsFetchInfo with empty parameters.""" info = DetailsFetchInfo(endpoint="/api/v1/listings/456") assert info.endpoint == "/api/v1/listings/456" assert info.parameters == {} class TestSummaryMetadata: """Test suite for SummaryMetadata model.""" def test_create_summary_metadata_preview(self): """Test creating preview metadata.""" metadata = SummaryMetadata( kind="preview", totalFields=20, projectedFields=["id", "status", "guestName"], detailsAvailable=DetailsFetchInfo(endpoint="/api/v1/bookings/123"), ) assert metadata.kind == "preview" assert metadata.totalFields == 20 assert metadata.projectedFields == ["id", "status", "guestName"] def test_create_summary_metadata_full(self): """Test creating full metadata.""" metadata = SummaryMetadata( kind="full", totalFields=20, projectedFields=["id"] * 20, detailsAvailable=DetailsFetchInfo(endpoint="/api/v1/bookings/123"), ) assert metadata.kind == "full" def test_summary_metadata_negative_total_fields(self): """Test validation error for negative totalFields.""" with pytest.raises(ValidationError): SummaryMetadata( kind="preview", totalFields=-5, projectedFields=["id"], detailsAvailable=DetailsFetchInfo(endpoint="/test"), ) class TestSummaryResponse: """Test suite for SummaryResponse model.""" def test_create_summary_response(self): """Test creating summary response.""" response = SummaryResponse[dict]( summary={"id": "BK12345", "status": "confirmed", "guestName": "John Doe"}, meta=SummaryMetadata( kind="preview", totalFields=20, projectedFields=["id", "status", "guestName"], detailsAvailable=DetailsFetchInfo( endpoint="/api/v1/bookings/BK12345", parameters={"fields": "all"} ), ), ) assert response.summary["id"] == "BK12345" assert response.summary["status"] == "confirmed" assert response.meta.kind == "preview" assert response.meta.totalFields == 20 def test_summary_response_empty_summary(self): """Test summary response with empty summary.""" response = SummaryResponse[dict]( summary={}, meta=SummaryMetadata( kind="preview", totalFields=0, projectedFields=[], detailsAvailable=DetailsFetchInfo(endpoint="/api/test"), ), ) assert response.summary == {} assert response.meta.projectedFields == [] class TestSummarizationStrategy: """Test suite for SummarizationStrategy model.""" def test_create_strategy_defaults(self): """Test creating strategy with defaults.""" strategy = SummarizationStrategy() assert strategy.strategy_type == "field_projection" assert strategy.essential_fields == [] assert strategy.max_nested_depth == 2 assert strategy.preserve_structure is True def test_create_strategy_field_projection(self): """Test creating field projection strategy.""" strategy = SummarizationStrategy( strategy_type="field_projection", essential_fields=["id", "status", "name"], max_nested_depth=3, preserve_structure=True, ) assert strategy.strategy_type == "field_projection" assert strategy.essential_fields == ["id", "status", "name"] assert strategy.max_nested_depth == 3 def test_create_strategy_extractive(self): """Test creating extractive strategy.""" strategy = SummarizationStrategy( strategy_type="extractive", essential_fields=["summary", "highlights"] ) assert strategy.strategy_type == "extractive" def test_create_strategy_abstractive(self): """Test creating abstractive strategy.""" strategy = SummarizationStrategy( strategy_type="abstractive", max_nested_depth=1, preserve_structure=False ) assert strategy.strategy_type == "abstractive" assert strategy.preserve_structure is False def test_strategy_invalid_nested_depth(self): """Test validation error for invalid nested depth.""" with pytest.raises(ValidationError): SummarizationStrategy(max_nested_depth=0) class TestSummarizationResult: """Test suite for SummarizationResult model.""" def test_create_summarization_result(self): """Test creating summarization result.""" result = SummarizationResult( original_field_count=20, summarized_field_count=5, reduction_ratio=0.75, original_tokens=1000, summarized_tokens=250, token_reduction=0.75, ) assert result.original_field_count == 20 assert result.summarized_field_count == 5 assert result.reduction_ratio == 0.75 assert result.original_tokens == 1000 assert result.summarized_tokens == 250 assert result.token_reduction == 0.75 def test_summarization_result_no_reduction(self): """Test summarization result with no reduction.""" result = SummarizationResult( original_field_count=10, summarized_field_count=10, reduction_ratio=0.0, original_tokens=500, summarized_tokens=500, token_reduction=0.0, ) assert result.reduction_ratio == 0.0 assert result.token_reduction == 0.0 def test_summarization_result_negative_counts(self): """Test validation error for negative counts.""" with pytest.raises(ValidationError): SummarizationResult( original_field_count=-5, summarized_field_count=5, reduction_ratio=0.5, original_tokens=100, summarized_tokens=50, token_reduction=0.5, ) def test_summarization_result_invalid_ratio(self): """Test validation error for invalid reduction ratio.""" with pytest.raises(ValidationError): SummarizationResult( original_field_count=10, summarized_field_count=5, reduction_ratio=1.5, # Invalid: > 1.0 original_tokens=100, summarized_tokens=50, token_reduction=0.5, ) class TestChunkMetadata: """Test suite for ChunkMetadata model.""" def test_create_chunk_metadata(self): """Test creating chunk metadata.""" metadata = ChunkMetadata(startLine=0, endLine=99, totalLines=500, bytesInChunk=4096) assert metadata.startLine == 0 assert metadata.endLine == 99 assert metadata.totalLines == 500 assert metadata.bytesInChunk == 4096 def test_chunk_metadata_validation_end_before_start(self): """Test validation error when endLine < startLine.""" with pytest.raises(ValidationError, match="endLine must be >= startLine"): ChunkMetadata(startLine=100, endLine=50, totalLines=500, bytesInChunk=1024) def test_chunk_metadata_validation_total_too_small(self): """Test validation error when totalLines <= endLine.""" with pytest.raises(ValidationError, match="totalLines must be > endLine"): ChunkMetadata( startLine=0, endLine=100, totalLines=100, # Should be > endLine bytesInChunk=1024, ) def test_chunk_metadata_equal_start_end(self): """Test chunk metadata with equal start and end lines.""" metadata = ChunkMetadata(startLine=50, endLine=50, totalLines=100, bytesInChunk=100) assert metadata.startLine == metadata.endLine class TestContentChunk: """Test suite for ContentChunk model.""" def test_create_content_chunk(self): """Test creating content chunk.""" chunk = ContentChunk( content="This is chunk 1 content...", chunkIndex=0, totalChunks=5, nextCursor="cursor-for-chunk-2", metadata=ChunkMetadata(startLine=0, endLine=99, totalLines=500, bytesInChunk=2048), ) assert chunk.content == "This is chunk 1 content..." assert chunk.chunkIndex == 0 assert chunk.totalChunks == 5 assert chunk.nextCursor == "cursor-for-chunk-2" assert chunk.metadata.startLine == 0 def test_content_chunk_last_chunk(self): """Test content chunk for last chunk (no next cursor).""" chunk = ContentChunk( content="This is the last chunk", chunkIndex=4, totalChunks=5, nextCursor=None, metadata=ChunkMetadata(startLine=400, endLine=499, totalLines=500, bytesInChunk=1024), ) assert chunk.chunkIndex == 4 assert chunk.totalChunks == 5 assert chunk.nextCursor is None def test_content_chunk_negative_index(self): """Test validation error for negative chunk index.""" with pytest.raises(ValidationError): ContentChunk( content="test", chunkIndex=-1, totalChunks=5, metadata=ChunkMetadata(startLine=0, endLine=10, totalLines=100, bytesInChunk=100), ) def test_content_chunk_zero_total(self): """Test validation error for zero total chunks.""" with pytest.raises(ValidationError): ContentChunk( content="test", chunkIndex=0, totalChunks=0, metadata=ChunkMetadata(startLine=0, endLine=10, totalLines=100, bytesInChunk=100), ) def test_content_chunk_empty_content(self): """Test content chunk with empty content.""" chunk = ContentChunk( content="", chunkIndex=0, totalChunks=1, metadata=ChunkMetadata(startLine=0, endLine=0, totalLines=1, bytesInChunk=0), ) assert chunk.content == "" assert chunk.metadata.bytesInChunk == 0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/darrentmorgan/hostaway-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server