Files
smart-support/backend/tests/unit/test_discount.py
Yaojia Wang 1050df780d feat: complete phase 2 -- multi-agent routing, interrupt TTL, escalation, templates
- Intent classification with LLM structured output (single/multi/ambiguous)
- Discount agent with apply_discount and generate_coupon tools
- Interrupt manager with 30-min TTL auto-expiration and retry prompts
- Webhook escalation module with exponential backoff retry (max 3)
- Three vertical industry templates (e-commerce, SaaS, fintech)
- Template loading in AgentRegistry
- Enhanced supervisor prompt with dynamic agent descriptions
- 153 tests passing, 90.18% coverage
2026-03-30 21:04:39 +02:00

80 lines
3.2 KiB
Python

"""Tests for app.agents.discount module."""
from __future__ import annotations
from unittest.mock import patch
import pytest
from app.agents.discount import apply_discount, generate_coupon
@pytest.mark.unit
class TestApplyDiscount:
def test_invalid_discount_zero(self) -> None:
result = apply_discount.invoke({"order_id": "1042", "discount_percent": 0})
assert result["status"] == "error"
assert "Invalid" in result["message"]
def test_invalid_discount_over_100(self) -> None:
result = apply_discount.invoke({"order_id": "1042", "discount_percent": 101})
assert result["status"] == "error"
def test_invalid_discount_negative(self) -> None:
result = apply_discount.invoke({"order_id": "1042", "discount_percent": -5})
assert result["status"] == "error"
@patch("app.agents.discount.interrupt", return_value=True)
def test_approved_discount(self, mock_interrupt) -> None:
result = apply_discount.invoke({"order_id": "1042", "discount_percent": 10})
assert result["status"] == "applied"
assert result["discount_percent"] == 10
assert "1042" in result["message"]
@patch("app.agents.discount.interrupt", return_value=False)
def test_rejected_discount(self, mock_interrupt) -> None:
result = apply_discount.invoke({"order_id": "1042", "discount_percent": 10})
assert result["status"] == "declined"
@patch("app.agents.discount.interrupt", return_value={"approved": True})
def test_approved_via_dict(self, mock_interrupt) -> None:
result = apply_discount.invoke({"order_id": "1042", "discount_percent": 50})
assert result["status"] == "applied"
@patch("app.agents.discount.interrupt", return_value={"approved": False})
def test_rejected_via_dict(self, mock_interrupt) -> None:
result = apply_discount.invoke({"order_id": "1042", "discount_percent": 50})
assert result["status"] == "declined"
@pytest.mark.unit
class TestGenerateCoupon:
def test_valid_coupon(self) -> None:
result = generate_coupon.invoke({"discount_percent": 15, "expiry_days": 7})
assert result["status"] == "generated"
assert result["discount_percent"] == 15
assert result["expiry_days"] == 7
assert result["coupon_code"].startswith("SAVE15-")
def test_default_expiry(self) -> None:
result = generate_coupon.invoke({"discount_percent": 20})
assert result["status"] == "generated"
assert result["expiry_days"] == 30
def test_invalid_discount_zero(self) -> None:
result = generate_coupon.invoke({"discount_percent": 0})
assert result["status"] == "error"
def test_invalid_discount_over_100(self) -> None:
result = generate_coupon.invoke({"discount_percent": 101})
assert result["status"] == "error"
def test_invalid_expiry(self) -> None:
result = generate_coupon.invoke({"discount_percent": 10, "expiry_days": 0})
assert result["status"] == "error"
def test_coupon_codes_unique(self) -> None:
r1 = generate_coupon.invoke({"discount_percent": 10})
r2 = generate_coupon.invoke({"discount_percent": 10})
assert r1["coupon_code"] != r2["coupon_code"]