"""Purchase objections and politics-in-book-context must stay in scope.""" import pytest from app.services.guardrails import check_boundary from app.services.intent import classify_intent @pytest.mark.asyncio async def test_purchase_objection_with_politics_not_off_topic_intent(): """'Why should I buy' + politics disinterest is a book question, not off-topic.""" query = "so why should i buy this, i have no interest in politics" result = await classify_intent(query, history=[]) assert result.intent == "question" assert result.intent != "off_topic" def test_purchase_objection_not_blocked_by_boundary(): """Boundary check must not reject in-scope purchase objections.""" query = "so why should i buy this, i have no interest in politics" violation, _ = check_boundary(query) assert violation is None @pytest.mark.asyncio async def test_politics_book_question_stays_in_scope(): """Discussing politics in the context of a political book is valid.""" result = await classify_intent("is it about donald trump?", history=[]) assert result.intent != "off_topic" @pytest.mark.asyncio async def test_weather_still_off_topic_intent(): """Genuine off-topic queries remain classified as off_topic.""" result = await classify_intent("what is the weather today", history=[]) assert result.intent == "off_topic" def test_stock_market_blocked_by_boundary(): """Non-book off-topic keywords still hit boundary guard.""" violation, _ = check_boundary("what is the stock market doing today") assert violation == "off_topic"