Spaces:
Running
Running
| """Suite B — Upsell engine link visibility rules (P0).""" | |
| import pytest | |
| from app.services.session_core.context import compute_interest_score | |
| from app.services.session_core.manager import SessionContext | |
| from app.services.upsell_engine import UpsellEngine, response_has_intrigue_hook | |
| def engine(): | |
| return UpsellEngine() | |
| def test_purchase_intent_always_shows_link(engine): | |
| ctx = SessionContext(session_id="s1", author_id="a1", turn_count=0) | |
| assert engine.should_include_link("purchase_intent", ctx, "DIRECT_CTA") is True | |
| def test_complaint_never_shows_link(engine): | |
| ctx = SessionContext( | |
| session_id="s1", | |
| author_id="a1", | |
| turn_count=5, | |
| selected_book_id="book-1", | |
| interest_score=0.9, | |
| ) | |
| strategy = engine.select_strategy("complaint", ctx) | |
| assert engine.should_include_link("complaint", ctx, strategy) is False | |
| def test_turn_two_with_selected_book_shows_link(engine): | |
| ctx = SessionContext( | |
| session_id="s1", | |
| author_id="a1", | |
| turn_count=2, | |
| selected_book_id="book-1", | |
| interest_score=0.2, | |
| ) | |
| strategy = engine.select_strategy("question", ctx) | |
| assert engine.should_include_link("question", ctx, strategy) is True | |
| def test_greeting_turn_one_no_link(engine): | |
| ctx = SessionContext(session_id="s1", author_id="a1", turn_count=0) | |
| strategy = engine.select_strategy("greeting", ctx) | |
| assert engine.should_include_link("greeting", ctx, strategy) is False | |
| def test_full_story_request_shows_link(engine): | |
| ctx = SessionContext(session_id="s1", author_id="a1", turn_count=0) | |
| strategy = engine.select_strategy("full_story_request", ctx) | |
| assert strategy == "DIRECT_CTA" | |
| assert engine.should_include_link("full_story_request", ctx, strategy) is True | |
| def test_book_comparison_uses_social_proof_at_medium_engagement(engine): | |
| ctx = SessionContext( | |
| session_id="s1", | |
| author_id="a1", | |
| turn_count=5, | |
| interest_score=0.5, | |
| ) | |
| strategy = engine.select_strategy("book_comparison", ctx) | |
| assert strategy == "SOCIAL_PROOF" | |
| def test_fallback_hook_skipped_when_intrigue_present(engine): | |
| text = "She carries a secret — want to know what it cost her?" | |
| assert engine.fallback_hook_if_needed(text, "CURIOSITY_GAP", 0.6) is None | |
| def test_fallback_hook_when_flat_response(engine): | |
| text = "The protagonist is brave." | |
| hook = engine.fallback_hook_if_needed(text, "CURIOSITY_GAP", 0.6) | |
| assert hook is not None | |
| assert response_has_intrigue_hook(hook) or len(hook) > 10 | |
| def test_pricing_intent_boosts_score(): | |
| cold = compute_interest_score(1, []) | |
| hot = compute_interest_score(1, ["pricing"], current_intent="purchase_intent") | |
| assert hot > cold | |
| assert hot >= 0.75 | |