"""Тесты для Validator.HTML"""
import pytest


class TestHTMLValidator:
    """Тесты HTML валидатора"""

    @pytest.fixture
    def sample_html(self):
        return """
        <html>
            <body>
                <div class="user">
                    <span class="username">john_doe</span>
                    <span class="status">Active</span>
                    <span class="age">25</span>
                </div>
                <div class="posts">
                    <a href="/post/1" class="post-link">First Post</a>
                    <a href="/post/2" class="post-link">Second Post</a>
                </div>
            </body>
        </html>
        """

    # ========== Проверка наличия/отсутствия ==========

    def test_validate_element_exists(self, sample_html):
        """Проверка наличия элемента"""
        from utils.json_path import Validator
        assert Validator.HTML(sample_html, "span.username", exists=True) is True

    def test_validate_element_not_exists(self, sample_html):
        """Проверка отсутствия элемента"""
        from utils.json_path import Validator
        assert Validator.HTML(sample_html, "div.error", exists=False) is True

    def test_validate_missing_element(self, sample_html):
        """Несуществующий элемент не проходит exists=True"""
        from utils.json_path import Validator
        assert Validator.HTML(sample_html, "div.missing", exists=True) is False

    # ========== CSS селекторы ==========

    def test_validate_css_class(self, sample_html):
        """Валидация CSS класса"""
        from utils.json_path import Validator
        assert Validator.HTML(sample_html, "span.username", exists=True) is True

    def test_validate_css_descendant(self, sample_html):
        """Валидация CSS потомка"""
        from utils.json_path import Validator
        assert Validator.HTML(sample_html, "div.user span.age", exists=True) is True

    # ========== XPath селекторы ==========

    def test_validate_xpath_simple(self, sample_html):
        """Валидация XPath селектора"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "//span[@class='username']",
            selector_type="xpath",
            exists=True
        ) is True

    def test_validate_xpath_contains(self, sample_html):
        """XPath с contains"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "//span[contains(@class, 'status')]",
            selector_type="xpath",
            exists=True
        ) is True

    # ========== Проверка значений ==========

    def test_validate_text_value(self, sample_html):
        """Проверка текстового значения"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "span.username",
            value="john_doe"
        ) is True

    def test_validate_wrong_value(self, sample_html):
        """Неправильное значение не проходит"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "span.username",
            value="alice"
        ) is False

    # ========== Проверка атрибутов ==========

    def test_validate_attr_value(self, sample_html):
        """Проверка значения атрибута"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "a.post-link",
            extract="attr",
            attr_name="href",
            value="/post/1"
        ) is True

    def test_validate_attr_exists(self, sample_html):
        """Проверка наличия атрибута"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "a.post-link",
            extract="attr",
            attr_name="href",
            exists=True
        ) is True

    # ========== Проверка типов ==========

    def test_validate_type_str(self, sample_html):
        """Проверка типа string"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "span.username",
            is_type=str
        ) is True

    # ========== Проверка диапазона ==========

    def test_validate_range(self, sample_html):
        """Проверка диапазона для числа"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "span.age",
            range_value=(20, 30)
        ) is True

    def test_validate_out_of_range(self, sample_html):
        """Значение вне диапазона"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "span.age",
            range_value=(30, 50)
        ) is False

    # ========== Проверка слов ==========

    def test_validate_words_match(self, sample_html):
        """Слова найдены"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "a.post-link",
            words=["First", "Post"]
        ) is True

    def test_validate_words_no_match(self, sample_html):
        """Слова не найдены"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "span.username",
            words=["alice", "bob"]
        ) is False

    # ========== Комбинированные проверки ==========

    def test_validate_combined(self, sample_html):
        """Комбинация проверок"""
        from utils.json_path import Validator
        assert Validator.HTML(
            sample_html,
            "span.age",
            exists=True,
            is_type=str,
            range_value=(20, 30)
        ) is True

    # ========== Невалидный HTML ==========

    def test_validate_invalid_html_exists_false(self):
        """Невалидный HTML + exists=False"""
        from utils.json_path import Validator
        assert Validator.HTML("invalid", "div", exists=False) is True

    def test_validate_invalid_html_exists_true(self):
        """Невалидный HTML + exists=True"""
        from utils.json_path import Validator
        assert Validator.HTML("invalid", "div", exists=True) is False