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."