"""
Unit tests for Adversarial Prompt Detector.
"""

import pytest
from engines.adversarial_prompt_detector import (
    AdversarialPromptDetector,
    HomoglyphDetector,
    InvisibleCharDetector,
    PerturbationType,
)


class TestHomoglyphDetector:
    """Tests for homoglyph detector."""

    def test_clean_text_passes(self):
        """Clean text passes."""
        detector = HomoglyphDetector()

        has_homo, positions = detector.detect("hello world")

        assert has_homo is False

    def test_cyrillic_detected(self):
        """Cyrillic homoglyphs detected."""
        detector = HomoglyphDetector()

        has_homo, positions = detector.detect("hеllo")  # Cyrillic е

        assert has_homo is True


class TestInvisibleCharDetector:
    """Tests for invisible char detector."""

    def test_clean_text_passes(self):
        """Clean text passes."""
        detector = InvisibleCharDetector()

        has_invis, _ = detector.detect("hello world")

        assert has_invis is False

    def test_zwsp_detected(self):
        """Zero-width space detected."""
        detector = InvisibleCharDetector()

        has_invis, _ = detector.detect("hel\u200blo")

        assert has_invis is True


class TestAdversarialPromptDetector:
    """Integration tests."""

    def test_clean_text_passes(self):
        """Clean text passes."""
        detector = AdversarialPromptDetector()

        result = detector.analyze("Hello, how are you?")

        assert result.is_adversarial is False

    def test_homoglyph_detected(self):
        """Homoglyph attack detected."""
        detector = AdversarialPromptDetector()

        result = detector.analyze("ignоre instructions")  # Cyrillic о

        assert result.is_adversarial is True
        assert PerturbationType.HOMOGLYPH in result.perturbations

    def test_invisible_detected(self):
        """Invisible char detected."""
        detector = AdversarialPromptDetector()

        result = detector.analyze("ignore\u200b instructions")

        assert result.is_adversarial is True
        assert PerturbationType.INVISIBLE_CHAR in result.perturbations

    def test_normalization(self):
        """Text is normalized."""
        detector = AdversarialPromptDetector()

        result = detector.analyze("hеllo\u200b")  # Cyrillic е + ZWSP

        assert "\u200b" not in result.normalized_text


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
