feat: jc 引擎主线搬入 app/engine(315 测试基线全绿:320 去掉 admin 5 用例)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
"""Red-line: `context` injection must be CONDITIONAL + WHITELIST only.
|
||||
|
||||
- No `context` passed -> `raw_info` stays `{}` (widget WS path unchanged).
|
||||
- `context` passed -> only `product_name`/`product_id` map to `app_*`.
|
||||
"""
|
||||
from sqlalchemy import select
|
||||
|
||||
from app.engine.models import CustomerProfile
|
||||
from app.engine.services.conversation import ConversationManager
|
||||
|
||||
|
||||
async def _raw_info_for(async_db, conv_id) -> dict:
|
||||
async with async_db() as db:
|
||||
result = await db.execute(
|
||||
select(CustomerProfile).where(
|
||||
CustomerProfile.conversation_id == conv_id
|
||||
)
|
||||
)
|
||||
profile = result.scalar_one()
|
||||
return profile.raw_info or {}
|
||||
|
||||
|
||||
async def test_no_context_keeps_raw_info_empty(async_db):
|
||||
async with async_db() as db:
|
||||
mgr = ConversationManager(db)
|
||||
conv = await mgr.create_conversation(context=None)
|
||||
raw = await _raw_info_for(async_db, conv.id)
|
||||
assert raw == {}
|
||||
|
||||
|
||||
async def test_context_seeds_whitelist_only(async_db):
|
||||
async with async_db() as db:
|
||||
mgr = ConversationManager(db)
|
||||
conv = await mgr.create_conversation(
|
||||
context={
|
||||
"product_name": "HDPE PE100 Pipe DN110",
|
||||
"product_id": "p123",
|
||||
"evil_key": "should_be_ignored",
|
||||
}
|
||||
)
|
||||
raw = await _raw_info_for(async_db, conv.id)
|
||||
assert raw == {
|
||||
"app_product_name": "HDPE PE100 Pipe DN110",
|
||||
"app_product_id": "p123",
|
||||
}
|
||||
Reference in New Issue
Block a user