ProfillyBot / tests /test_response_enhancer.py
MinhDS's picture
Deploy ProfillyBot: Gradio ZeroGPU + CV RAG (Qwen2.5-3B)
0828c2c verified
Raw
History Blame Contribute Delete
8.98 kB
"""Tests for response enhancer module."""
import re
from unittest.mock import patch
import pytest
from src.response_enhancer import ResponseEnhancer, get_response_enhancer
@pytest.fixture
def enhancer():
"""Create a ResponseEnhancer instance for testing."""
with patch("src.response_enhancer.get_config") as mock_config:
mock_config.return_value.get.return_value = "Tin Hoang"
return ResponseEnhancer()
# --- ResponseEnhancer Tests ---
def test_enhancer_init(enhancer):
"""Test ResponseEnhancer initialization."""
assert enhancer is not None
assert enhancer.name == "Tin Hoang"
assert len(enhancer.negative_patterns) > 0
assert len(enhancer.positive_closings) > 0
def test_enhance_empty_response(enhancer):
"""Test enhance handles empty response."""
result = enhancer.enhance("")
assert result == ""
# Whitespace-only gets stripped and returns empty
result = enhancer.enhance(" ")
assert result.strip() == ""
def test_enhance_none_response(enhancer):
"""Test enhance handles None response."""
result = enhancer.enhance(None)
assert result is None
def test_enhance_simple_response(enhancer):
"""Test enhance keeps simple responses unchanged."""
response = "Tin is an AI Engineer with expertise in machine learning."
result = enhancer.enhance(response)
assert "Tin" in result or "AI Engineer" in result
def test_rewrite_no_info_pattern(enhancer):
"""Test rewriting 'don't have information' pattern."""
response = "However, I don't have any specific information about that topic."
result = enhancer.enhance(response)
# Should not contain the negative phrase
assert "don't have" not in result.lower()
assert "however" not in result.lower() or "directly" in result.lower()
def test_rewrite_uncertain_pattern(enhancer):
"""Test rewriting uncertain statements."""
response = "I'm not sure about the specific salary expectations."
result = enhancer.enhance(response)
# Should not contain the uncertain phrase
assert "not sure" not in result.lower()
def test_rewrite_cannot_provide_pattern(enhancer):
"""Test rewriting 'cannot provide' statements."""
response = "I cannot provide more information about his personal life."
result = enhancer.enhance(response)
# Should not contain the negative phrase
assert "cannot provide" not in result.lower()
def test_rewrite_do_not_have_pattern(enhancer):
"""Test rewriting 'do not have' statements."""
response = "I do not have any details about that project."
result = enhancer.enhance(response)
# Should not contain the negative phrase
assert "do not have" not in result.lower()
def test_add_positive_closing_negative_ending(enhancer):
"""Test adding positive closing for negative endings."""
response = "The profile covers relevant experience. However, there's no information available."
result = enhancer.enhance(response)
# Should have some form of positive closing
assert len(result) >= len(response)
def test_no_double_closing(enhancer):
"""Test no double closing when already has contact suggestion."""
response = "For more details, feel free to connect directly with me."
result = enhancer.enhance(response)
# Should not add another closing
assert result.count("directly") <= 2
def test_fix_markdown_inline_numbered_list(enhancer):
"""Test fixing inline numbered lists."""
response = "Key skills: 1. Python 2. Machine Learning 3. Deep Learning"
result = enhancer.enhance(response)
# Should format the list properly
assert result is not None
def test_fix_markdown_already_formatted_list(enhancer):
"""Test preserving already formatted lists."""
response = """Key skills:
1. Python
2. Machine Learning
3. Deep Learning"""
result = enhancer.enhance(response)
# Should preserve the formatting
assert "1." in result
assert "2." in result
assert "3." in result
def test_cleanup_double_spaces(enhancer):
"""Test cleanup of double spaces."""
response = "This has multiple spaces."
result = enhancer.enhance(response)
assert " " not in result
def test_cleanup_punctuation(enhancer):
"""Test cleanup of awkward punctuation."""
response = "This has extra spaces before punctuation ."
result = enhancer.enhance(response)
assert " ." not in result
def test_cleanup_double_punctuation(enhancer):
"""Test cleanup of double punctuation."""
response = "This has double punctuation.."
result = enhancer.enhance(response)
# Should have single punctuation
assert ".." not in result
def test_enhance_with_context_job_search(enhancer):
"""Test enhance_with_context adds job-related closing."""
question = "What job roles are you looking for?"
response = "The candidate has experience in AI and ML engineering."
result = enhancer.enhance_with_context(response, question)
# Should add contact suggestion for job-related questions
assert "direct" in result.lower() or "contact" in result.lower()
def test_enhance_with_context_already_has_contact(enhancer):
"""Test enhance_with_context doesn't add duplicate contact suggestion."""
question = "What position are you seeking?"
response = "Looking for ML roles. Feel free to reach out to discuss opportunities."
result = enhancer.enhance_with_context(response, question)
# Should not add another contact suggestion
assert result.count("reach out") <= 1
def test_enhance_with_context_non_job_question(enhancer):
"""Test enhance_with_context for non-job questions."""
question = "What are your technical skills?"
response = "Strong background in Python, TensorFlow, and PyTorch."
result = enhancer.enhance_with_context(response, question)
# Should be similar to original (no job-specific closing added)
assert "Python" in result
# --- Rewrite Function Tests ---
def test_rewrite_no_info_consistent(enhancer):
"""Test _rewrite_no_info produces consistent output for same topic."""
pattern = r"(?:I\s+)?(?:don'?t|do\s+not)\s+have\s+(?:any\s+)?(?:more\s+)?(?:information|details|data)\s+(?:about|on|regarding)\s+([^.!?]+)"
text = "I don't have any information about salary expectations."
match = re.search(pattern, text, re.IGNORECASE)
if match:
result1 = enhancer._rewrite_no_info(match)
result2 = enhancer._rewrite_no_info(match)
# Same topic should produce same rewrite
assert result1 == result2
def test_rewrite_uncertain_consistent(enhancer):
"""Test _rewrite_uncertain produces consistent output for same topic."""
pattern = r"(?:I'm|I am)\s+(?:not\s+)?(?:un)?(?:sure|certain|aware)\s+(?:about|of)\s+([^.!?]+)"
text = "I'm not sure about the project timeline."
match = re.search(pattern, text, re.IGNORECASE)
if match:
result1 = enhancer._rewrite_uncertain(match)
result2 = enhancer._rewrite_uncertain(match)
# Same topic should produce same rewrite
assert result1 == result2
def test_rewrite_cannot_provide_consistent(enhancer):
"""Test _rewrite_cannot_provide produces consistent output for same topic."""
pattern = r"(?:I\s+)?(?:cannot|can'?t|unable to)\s+(?:provide|share|give)\s+(?:more\s+)?(?:information|details)\s+(?:about|on)\s+([^.!?]+)"
text = "I cannot provide more details about that."
match = re.search(pattern, text, re.IGNORECASE)
if match:
result1 = enhancer._rewrite_cannot_provide(match)
result2 = enhancer._rewrite_cannot_provide(match)
# Same topic should produce same rewrite
assert result1 == result2
# --- Markdown Formatting Tests ---
def test_fix_markdown_bullet_list(enhancer):
"""Test handling bullet lists."""
response = """Skills include:
- Python
- Machine Learning
- Deep Learning"""
result = enhancer._fix_markdown_formatting(response)
assert "-" in result
assert "Python" in result
def test_fix_markdown_mixed_content(enhancer):
"""Test handling mixed content."""
response = """Overview paragraph.
1. First item
2. Second item
Another paragraph."""
result = enhancer._fix_markdown_formatting(response)
assert "1." in result
assert "2." in result
def test_fix_markdown_no_multiple_blank_lines(enhancer):
"""Test no multiple blank lines."""
response = """First paragraph.
Second paragraph."""
result = enhancer._fix_markdown_formatting(response)
# Should not have multiple consecutive blank lines
assert "\n\n\n" not in result
# --- Factory Function Tests ---
def test_get_response_enhancer():
"""Test get_response_enhancer returns instance."""
with patch("src.response_enhancer.get_config") as mock_config:
mock_config.return_value.get.return_value = "Test Name"
result = get_response_enhancer()
assert isinstance(result, ResponseEnhancer)