chatassistant_retail / tests /integration /test_tool_context_integration.py
github-actions[bot]
Sync from https://github.com/samir72/chatassistant_retail
8b30412
"""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
@pytest.mark.asyncio
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
@pytest.mark.asyncio
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
@pytest.mark.asyncio
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"
@pytest.mark.asyncio
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
@pytest.mark.asyncio
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
@pytest.mark.asyncio
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
@pytest.mark.asyncio
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
@pytest.mark.asyncio
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
@pytest.mark.asyncio
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