work_item: ORCH-069
description: >
  Юнит-тесты для конфигурируемого верхнего лимита длины заголовка QG-0
  (_qg0_errors) через параметр settings.qg0_title_max (env ORCH_QG0_TITLE_MAX,
  дефолт 200). Тесты патчат settings.qg0_title_max (monkeypatch на объекте
  src.config.settings, который импортирован в src.webhooks.plane) и проверяют
  границы и тексты ошибок. Файл тестов: tests/test_qg0_title_limit.py.

tests:
  - id: TC-01
    type: unit
    description: "Дефолтный лимит 200: заголовок ровно 200 символов -> нет ошибки длины title (PASS на границе)."
    module: tests/test_qg0_title_limit.py
    setup: "settings.qg0_title_max=200 (дефолт); name='x'*200; description валиден (>=20 символов)."
    assert: "В списке _qg0_errors нет элемента про длину title."
    covers: [AC-1]
    expected: PASS

  - id: TC-02
    type: unit
    description: "Дефолтный лимит 200: заголовок 201 символ -> ошибка длины title, текст упоминает '200'."
    module: tests/test_qg0_title_limit.py
    setup: "settings.qg0_title_max=200; name='x'*201; description валиден."
    assert: "В _qg0_errors есть ошибка длины title и её текст содержит подстроку '200'."
    covers: [AC-1]
    expected: PASS

  - id: TC-03
    type: unit
    description: "Настраиваемый лимит 120: заголовок 120 символов -> нет ошибки длины title."
    module: tests/test_qg0_title_limit.py
    setup: "monkeypatch settings.qg0_title_max=120; name='x'*120; description валиден."
    assert: "Нет ошибки длины title."
    covers: [AC-2]
    expected: PASS

  - id: TC-04
    type: unit
    description: "Настраиваемый лимит 120: заголовок 121 символ -> ошибка длины title, текст упоминает '120'."
    module: tests/test_qg0_title_limit.py
    setup: "monkeypatch settings.qg0_title_max=120; name='x'*121; description валиден."
    assert: "Есть ошибка длины title и её текст содержит подстроку '120' (и НЕ '80')."
    covers: [AC-2]
    expected: PASS

  - id: TC-05
    type: unit
    description: "Graceful: невалидное (нечисловое) значение env ORCH_QG0_TITLE_MAX не роняет инстанцирование Settings и даёт дефолт 200."
    module: tests/test_qg0_title_limit.py
    setup: "monkeypatch.setenv('ORCH_QG0_TITLE_MAX','abc'); создать новый экземпляр Settings()."
    assert: "Settings() не выбрасывает исключение; settings.qg0_title_max == 200."
    covers: [AC-3]
    expected: PASS

  - id: TC-06
    type: unit
    description: "Graceful: пустая строка env ORCH_QG0_TITLE_MAX -> дефолт 200, без исключения."
    module: tests/test_qg0_title_limit.py
    setup: "monkeypatch.setenv('ORCH_QG0_TITLE_MAX',''); создать новый экземпляр Settings()."
    assert: "Settings() не падает; settings.qg0_title_max == 200."
    covers: [AC-3]
    expected: PASS

  - id: TC-07
    type: unit
    description: "Корректное числовое env -> применяется заданное значение (sanity положительного пути)."
    module: tests/test_qg0_title_limit.py
    setup: "monkeypatch.setenv('ORCH_QG0_TITLE_MAX','150'); создать новый экземпляр Settings()."
    assert: "settings.qg0_title_max == 150."
    covers: [AC-2, AC-3]
    expected: PASS

  - id: TC-08
    type: unit
    description: "Нижний лимит title не сломан: заголовок < 5 символов -> ошибка 'Title слишком короткий' при любом верхнем лимите."
    module: tests/test_qg0_title_limit.py
    setup: "settings.qg0_title_max=200; name='abc' (3 символа); description валиден."
    assert: "В _qg0_errors есть ошибка короткого title."
    covers: [AC-4]
    expected: PASS

  - id: TC-09
    type: unit
    description: "Лимит description не сломан: description < 20 символов -> ошибка 'Description слишком короткий'."
    module: tests/test_qg0_title_limit.py
    setup: "settings.qg0_title_max=200; name валиден (>=5, <=200); description='short'."
    assert: "В _qg0_errors есть ошибка короткого description."
    covers: [AC-4]
    expected: PASS

  - id: TC-10
    type: unit
    description: "Обратная совместимость: заголовок длиной 81-200 (ранее отклонялся лимитом 80) теперь проходит при дефолте."
    module: tests/test_qg0_title_limit.py
    setup: "settings.qg0_title_max=200; name='x'*100; description валиден."
    assert: "Нет ошибки длины title (раньше при лимите 80 была бы)."
    covers: [AC-7]
    expected: PASS

  - id: TC-11
    type: unit
    description: "Полный набор тестов зелёный (регрессия не внесена)."
    module: tests/
    command: "pytest tests/ -q"
    assert: "Все тесты проходят."
    covers: [AC-5]
    expected: PASS

notes:
  - "settings импортирован в src.webhooks.plane как 'from ..config import settings', _qg0_errors читает settings.qg0_title_max динамически -> monkeypatch на src.config.settings.qg0_title_max (или импортируемом объекте) меняет поведение в рамках теста."
  - "Для TC-05/06/07 нужен СВЕЖИЙ экземпляр Settings(): глобальный src.config.settings создаётся один раз на импорт, поэтому env-тесты инстанцируют Settings() локально, а не полагаются на готовый синглтон."
  - "Тесты не требуют сети, БД, агентов или FastAPI TestClient — чистая проверка leaf-функции _qg0_errors и парсинга Settings."
