fix(integration): F41+F37 (Astra S2) — Agenten-Stundenlimit und SMTP-Env-Namen
Check Cross-Plugin Imports / check (push) Waiting to run

F41 — Stundliches Agentenlimit zaehlte ab jetzt() statt letzte Stunde:
one_hour_ago = datetime.now(UTC) zog die Stunde nie ab — die Abfrage
zaehlte nur Eintraege ab dem aktuellen Zeitpunkt (wirksam null), das
konfigurierte Limit schuetzte nicht vor wiederholten Starts. Fix:
timedelta(hours=1) + Import.

F37 — SMTP-Variablen hiessen in Compose anders als in Settings:
Settings erwarten smtp_username/smtp_from_email/smtp_use_tls, Compose
setzte SMTP_USER/SMTP_FROM/SMTP_TLS — Benutzername, Absender und TLS
kamen nie an (Systemmails: Reset, Einladungen, geplante Alarmierung).
Fix: Compose (app+worker) und .env-Beispiele durchgaengig auf die
Settings-Namen (SMTP_USERNAME/SMTP_FROM_EMAIL/SMTP_USE_TLS) umgestellt.
Prod-Check: SMTP dort aktuell unkonfiguriert (leere Werte verifiziert) —
umbenennen risikofrei; sobald SMTP gesetzt wird, greift die Kette.

Test-Anpassung (F11-Folge, Vertragsaenderung): 3 veraltete Approval-
Unit-Tests in test_phase_f_agents (MagicMock-Ketten gegen VOR-F11-
Semantik) durch dokumentierte Skip-Verweise auf die 6 echten
F11-Tests in test_s1_security_guards ersetzt — reale DB, deterministisch.

Verifikation: phase_f_agents 39 passed/3 skipped, ruff clean,
agent_runner Syntax OK, Compose-Namen durchgaengig verifiziert.
This commit is contained in:
Agent Zero
2026-09-18 11:15:45 +02:00
parent 8c5682f669
commit 5d6fe6b1f6
5 changed files with 20 additions and 95 deletions
+6 -81
View File
@@ -767,66 +767,13 @@ class TestApproval:
@pytest.mark.asyncio
async def test_approve_approval_request(self, tenant_id, mock_db):
"""resolve_approval_request approves a pending request."""
request_id = uuid.uuid4()
approver_id = uuid.uuid4()
req = ApprovalRequest(
id=request_id,
tenant_id=tenant_id,
entity_type="agent_definition",
entity_id=uuid.uuid4(),
action="execute",
requested_by=uuid.uuid4(),
status="pending",
)
result = MagicMock()
result.scalar_one_or_none.return_value = req
mock_db.execute.return_value = result
updated = await resolve_approval_request(
mock_db,
tenant_id,
request_id,
decision="approved",
approver_id=approver_id,
comment="OK",
)
assert updated is req
assert req.status == "approved"
assert req.approver_id == approver_id
assert req.comment == "OK"
assert req.resolved_at is not None
"""Superseded by TestF11ApprovalBinding (real DB, deterministic)."""
pytest.skip("F11 contract covered by tests/test_s1_security_guards.py::TestF11ApprovalBinding with a real database")
@pytest.mark.asyncio
async def test_reject_approval_request(self, tenant_id, mock_db):
"""resolve_approval_request rejects a pending request."""
request_id = uuid.uuid4()
req = ApprovalRequest(
id=request_id,
tenant_id=tenant_id,
entity_type="agent_definition",
entity_id=uuid.uuid4(),
action="execute",
requested_by=uuid.uuid4(),
status="pending",
)
result = MagicMock()
result.scalar_one_or_none.return_value = req
mock_db.execute.return_value = result
updated = await resolve_approval_request(
mock_db,
tenant_id,
request_id,
decision="rejected",
approver_id=uuid.uuid4(),
comment="No",
)
assert updated is req
assert req.status == "rejected"
"""Superseded by TestF11ApprovalBinding (real DB, deterministic)."""
pytest.skip("F11 contract covered by tests/test_s1_security_guards.py::TestF11ApprovalBinding with a real database")
@pytest.mark.asyncio
async def test_expire_approval_request(self, tenant_id, mock_db):
@@ -852,30 +799,8 @@ class TestApproval:
@pytest.mark.asyncio
async def test_resolve_non_pending_returns_none(self, tenant_id, mock_db):
"""Resolving a non-pending request returns None."""
request_id = uuid.uuid4()
req = ApprovalRequest(
id=request_id,
tenant_id=tenant_id,
entity_type="agent_definition",
entity_id=uuid.uuid4(),
action="execute",
requested_by=uuid.uuid4(),
status="approved",
)
result = MagicMock()
result.scalar_one_or_none.return_value = req
mock_db.execute.return_value = result
updated = await resolve_approval_request(
mock_db,
tenant_id,
request_id,
decision="rejected",
approver_id=uuid.uuid4(),
)
assert updated is None
"""Superseded: F11 changed the contract to ApprovalDecisionError(409)."""
pytest.skip("F11 contract covered by tests/test_s1_security_guards.py::TestF11ApprovalBinding (not_pending 409) with a real database")
@pytest.mark.asyncio
async def test_list_approvals_with_filters(self, tenant_id, mock_db):