Текущая стабильная сборка с исправлением интеграционных косяков

This commit is contained in:
mi
2026-08-20 11:03:32 +03:00
parent c7a80e7256
commit 6e24278b10
12 changed files with 127 additions and 32 deletions
@@ -37,8 +37,25 @@ def test_full_mode_rejects_portal_host_mismatch() -> None:
def test_rest_field_conversion_is_deterministic() -> None:
assert Settings.rest_field_name("UF_CRM_1778692456") == "ufCrm_1778692456"
assert Settings.rest_field_name("UF_CRM_6a70c275346a7") == "ufCrm_6a70c275346a7"
assert Settings.rest_field_name("UF_CRM_AbC123") == "ufCrm_AbC123"
with pytest.raises(ValueError):
Settings.rest_field_name("uf_crm_1")
with pytest.raises(ValueError):
Settings.rest_field_name("UF_CRM_123_abc")
def test_image_default_allows_compose_process_role_override() -> None:
service_root = Path(__file__).parents[1]
dockerfile = (service_root / "Dockerfile").read_text(encoding="utf-8")
compose = (service_root / "compose.fragment.yaml").read_text(encoding="utf-8")
production_compose = (service_root.parent / "docker-compose.yml").read_text(encoding="utf-8")
assert 'CMD ["han-bitrix-sync-api"]' in dockerfile
assert 'ENTRYPOINT ["han-bitrix-sync-api"]' not in dockerfile
for source in (compose, production_compose):
assert 'command: ["han-bitrix-sync-worker"]' in source
assert 'command: ["han-bitrix-sync-reconciliation"]' in source
def test_alembic_chain_preserves_legacy_baseline() -> None:
@@ -4,9 +4,10 @@ import uuid
from contextlib import asynccontextmanager
import pytest
from sqlalchemy.dialects.postgresql import JSONB
from app.crm import CrmOutcome, CrmResult
from app.engine import WorkflowEngine
from app.engine import INSERT_CRM_COMMAND, UPDATE_CRM_COMMAND, WorkflowEngine
from app.repository import Profile
@@ -57,6 +58,11 @@ class FakeCrm:
return CrmResult(CrmOutcome.SUCCEEDED, True)
def test_crm_command_json_payloads_have_explicit_jsonb_types() -> None:
assert isinstance(INSERT_CRM_COMMAND._bindparams["safe_request"].type, JSONB)
assert isinstance(UPDATE_CRM_COMMAND._bindparams["safe_response"].type, JSONB)
@pytest.mark.asyncio
async def test_multiple_contacts_choose_numeric_newest(full_settings) -> None:
user_id = uuid.uuid4()
@@ -0,0 +1,57 @@
from __future__ import annotations
from contextlib import asynccontextmanager
from types import SimpleNamespace
import pytest
from app.repository import Repository
class FakeResult:
def __init__(self, *, rows=(), scalar=None) -> None:
self.rows = rows
self.scalar = scalar
def __iter__(self):
return iter(self.rows)
def scalar_one_or_none(self):
return self.scalar
class FakeConnection:
async def execute(self, statement):
sql = str(statement)
if "han_app.sync_queue" in sql:
return FakeResult(rows=[SimpleNamespace(status="pending", count=2)])
if "workflow_instances" in sql:
assert "state AS status" in sql
return FakeResult(rows=[SimpleNamespace(status="created", count=3)])
if "crm_commands" in sql:
return FakeResult(rows=[SimpleNamespace(status="succeeded", count=4)])
if "webhook_inbox" in sql:
return FakeResult(scalar=1.5)
if "settings_versions" in sql:
return FakeResult(scalar=1)
raise AssertionError(f"unexpected status query: {sql}")
class FakeEngine:
@asynccontextmanager
async def connect(self):
yield FakeConnection()
@pytest.mark.asyncio
async def test_status_uses_common_status_alias_for_workflows() -> None:
repository = object.__new__(Repository)
repository.engine = FakeEngine()
result = await repository.status()
assert result["queue"] == {"pending": 2}
assert result["workflows"] == {"created": 3}
assert result["commands"] == {"succeeded": 4}
assert result["webhook_lag_seconds"] == 1.5
assert result["settings_version"] == 1