"""Client mirror from GTI Gerenciador (central/app/client_sync.py, web.py's /agents/new). GTI Gerenciador is the single source of truth: Tenant rows with source='GTI_GERENCIADOR' are upserted from it; source='LOCAL' rows (pre-existing dev/test tenants) are never touched or offered.""" import dataclasses import pytest from sqlalchemy import select from central.app import client_sync, config from central.app.models import Tenant from central.tests.test_control_plane import setup_db CLIENTS = [ {"external_client_id": 1, "code": "000001", "display_name": "Mercado Ativo", "active": True}, {"external_client_id": 2, "code": "000002", "display_name": "Loja Inativa", "active": False}, ] @pytest.fixture def factory(): return setup_db() def test_sync_creates_tenants_from_gerenciador(factory): with factory() as session: result = client_sync.sync_from_gerenciador(session, CLIENTS) session.commit() assert result.created == 2 and result.updated == 0 and result.fetched == 2 assert result.active == 1 and result.inactive == 1 rows = {row.external_client_id: row for row in session.scalars(select(Tenant)).all()} assert rows[1].name == "Mercado Ativo" and rows[1].source == "GTI_GERENCIADOR" and rows[1].active is True assert rows[2].active is False and rows[2].external_code == "000002" def test_sync_is_idempotent_and_updates_changed_fields(factory): with factory() as session: client_sync.sync_from_gerenciador(session, CLIENTS) session.commit() result = client_sync.sync_from_gerenciador(session, CLIENTS) session.commit() assert result.created == 0 and result.unchanged == 2 renamed = [{**CLIENTS[0], "display_name": "Mercado Ativo Renomeado"}, CLIENTS[1]] result2 = client_sync.sync_from_gerenciador(session, renamed) session.commit() assert result2.updated == 1 and result2.unchanged == 1 row = session.scalar(select(Tenant).where(Tenant.external_client_id == 1)) assert row.name == "Mercado Ativo Renomeado" def test_sync_never_touches_local_tenants(factory): with factory() as session: session.add(Tenant(name="Acme", source="LOCAL")) session.commit() client_sync.sync_from_gerenciador(session, CLIENTS) session.commit() local = session.scalar(select(Tenant).where(Tenant.name == "Acme")) assert local.source == "LOCAL" and local.external_client_id is None def test_sync_disambiguates_a_name_collision_with_an_existing_tenant(factory): with factory() as session: session.add(Tenant(name="Mercado Ativo", source="LOCAL")) session.commit() client_sync.sync_from_gerenciador(session, CLIENTS) session.commit() new_row = session.scalar(select(Tenant).where(Tenant.external_client_id == 1)) assert new_row.name == "Mercado Ativo (000001)" # the LOCAL tenant keeps the plain name def test_deactivating_a_client_in_gerenciador_is_reflected_without_deleting_history(factory): with factory() as session: client_sync.sync_from_gerenciador(session, CLIENTS) session.commit() now_inactive = [{**CLIENTS[0], "active": False}, CLIENTS[1]] client_sync.sync_from_gerenciador(session, now_inactive) session.commit() row = session.scalar(select(Tenant).where(Tenant.external_client_id == 1)) assert row.active is False # row (and every FK pointing at it) is kept — never deleted def test_disabled_without_configured_url_or_token(monkeypatch): monkeypatch.setattr(config, "settings", dataclasses.replace(config.settings, gerenciador_internal_url="", fiscal_internal_api_token="")) assert client_sync.enabled() is False with pytest.raises(client_sync.ClientSyncUnavailable): client_sync.fetch_from_gerenciador()