Spaces:
Sleeping
Sleeping
| """Integration tests for context-aware tool functionality.""" | |
| from __future__ import annotations | |
| import pytest | |
| from chatassistant_retail.state.langgraph_manager import ConversationState | |
| from chatassistant_retail.tools.inventory_tools import ( | |
| calculate_reorder_point_impl, | |
| query_inventory_impl, | |
| ) | |
| from chatassistant_retail.tools.purchase_order_tools import create_purchase_order_impl | |
| async def test_query_inventory_without_state(): | |
| """Test query_inventory works without state (backward compatibility).""" | |
| result = await query_inventory_impl(sku="SKU-10000") | |
| assert result["success"] is True | |
| assert len(result["products"]) >= 1 | |
| async def test_query_inventory_with_empty_state(): | |
| """Test query_inventory falls back to fresh load with empty state.""" | |
| state = ConversationState(session_id="test") | |
| result = await query_inventory_impl(sku="SKU-10000", state=state) | |
| assert result["success"] is True | |
| assert len(result["products"]) >= 1 | |
| # State should now have products_cache populated | |
| assert "products_cache" in state.context | |
| async def test_query_inventory_uses_context(): | |
| """Test query_inventory reuses products from context.""" | |
| # Create state with pre-populated product cache | |
| test_product = { | |
| "sku": "SKU-10000", | |
| "name": "Test Laptop", | |
| "category": "Electronics", | |
| "price": 999.99, | |
| "current_stock": 5, | |
| "reorder_level": 10, | |
| "supplier": "Test Supplier", | |
| "description": "Test description", | |
| } | |
| state = ConversationState( | |
| session_id="test", | |
| context={ | |
| "products_cache": { | |
| "data": [test_product], | |
| "source": "rag", | |
| "timestamp": 123456.0, | |
| "filter_applied": {"sku": "SKU-10000"}, | |
| } | |
| }, | |
| ) | |
| result = await query_inventory_impl(sku="SKU-10000", state=state) | |
| assert result["success"] is True | |
| assert len(result["products"]) == 1 | |
| assert result["products"][0]["name"] == "Test Laptop" | |
| async def test_calculate_reorder_point_without_state(): | |
| """Test calculate_reorder_point works without state (backward compatibility).""" | |
| result = await calculate_reorder_point_impl(sku="SKU-10000") | |
| # May succeed or fail depending on whether product exists and has sales | |
| assert "success" in result | |
| async def test_calculate_reorder_point_with_state(): | |
| """Test calculate_reorder_point caches products when loading fresh.""" | |
| state = ConversationState(session_id="test") | |
| result = await calculate_reorder_point_impl(sku="SKU-10000", state=state) | |
| if result["success"]: | |
| # State should have products_cache populated | |
| assert "products_cache" in state.context | |
| async def test_create_purchase_order_without_state(): | |
| """Test create_purchase_order works without state (backward compatibility).""" | |
| result = await create_purchase_order_impl(sku="SKU-10000", quantity=10) | |
| # May succeed or fail depending on whether product exists | |
| assert "success" in result | |
| async def test_create_purchase_order_with_state(): | |
| """Test create_purchase_order caches products when loading fresh.""" | |
| state = ConversationState(session_id="test") | |
| result = await create_purchase_order_impl(sku="SKU-10000", quantity=10, state=state) | |
| if result["success"]: | |
| # State should have products_cache populated | |
| assert "products_cache" in state.context | |
| async def test_multi_tool_context_reuse(): | |
| """Test multiple tools sharing context data.""" | |
| state = ConversationState(session_id="test") | |
| # First tool call: query_inventory loads and caches data | |
| result1 = await query_inventory_impl(sku="SKU-10000", state=state) | |
| assert result1["success"] is True | |
| assert "products_cache" in state.context | |
| initial_cache = state.context["products_cache"] | |
| # Second tool call: calculate_reorder_point should reuse cached product | |
| result2 = await calculate_reorder_point_impl(sku="SKU-10000", state=state) | |
| if result2["success"]: | |
| # Cache should still be there (may have been updated with sales data) | |
| assert "products_cache" in state.context | |
| # Third tool call: create_purchase_order should also reuse cache | |
| result3 = await create_purchase_order_impl(sku="SKU-10000", quantity=10, state=state) | |
| if result3["success"]: | |
| # Cache should still be present | |
| assert "products_cache" in state.context | |
| async def test_rag_to_tool_workflow(): | |
| """Test workflow where RAG populates context, then tool uses it.""" | |
| # Simulate RAG having populated products in context | |
| rag_product = { | |
| "sku": "SKU-10000", | |
| "name": "Laptop Pro", | |
| "category": "Electronics", | |
| "price": 1299.99, | |
| "current_stock": 5, | |
| "reorder_level": 10, | |
| "supplier": "Tech Supplies Inc.", | |
| "description": "High-performance laptop", | |
| } | |
| state = ConversationState( | |
| session_id="test", | |
| context={ | |
| "products": [rag_product], # Simulating RAG results | |
| "products_cache": { | |
| "data": [rag_product], | |
| "source": "rag", | |
| "timestamp": 123456.0, | |
| "filter_applied": {"query": "laptop"}, | |
| }, | |
| }, | |
| ) | |
| # Tool should be able to use the RAG-retrieved product | |
| result = await query_inventory_impl(sku="SKU-10000", state=state) | |
| assert result["success"] is True | |
| # Should use cached data | |
| assert len(result["products"]) == 1 | |