Engine honours org policy and monthly budget, legacy runner skips engine tasks, sandbox session provisioned on demand, project fallback for threads, reviewer fallback, tenant checks on project ids, memory reflection respects grants, expiry worker, MCP pipeline_status, login redirect, sharing settings, e2e smoke. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
71 lines
3.2 KiB
Python
71 lines
3.2 KiB
Python
"""Integration: hiring respects the owner's per-organization employee cap.
|
|
|
|
The team is capped by two numbers: the owner's ``max_employees`` in the org
|
|
policy, and the global ``settings.engine_max_employees``. The lower one wins. The
|
|
owner can tighten the cap for their organization, but cannot lift it above the
|
|
global limit.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from app.application.ports.model_grants import DefaultOrgPolicy
|
|
from app.core.config import settings
|
|
from app.core.errors import ConflictError
|
|
from app.domain.workforce.models import RoleKey
|
|
from app.infrastructure.repositories.workforce import EmployeeRepository
|
|
from tests.engine_fakes import FakeGrants, ScriptedModel
|
|
from tests.test_engine_manager import _manager
|
|
from tests.test_engine_manager import world as manager_world
|
|
|
|
#: The manager tests' organization fixture. Binding it under its own name registers it
|
|
#: for this module's tests (a bare import would be flagged as unused and shadowed).
|
|
world = manager_world
|
|
|
|
|
|
async def _hire_tester(manager, world):
|
|
return await manager.hire(
|
|
organization_id=world.organization_id, role=RoleKey.TESTER, tier="fast"
|
|
)
|
|
|
|
|
|
async def test_the_owner_policy_caps_the_team(world, session_factory):
|
|
"""An owner's ``max_employees`` of 2 refuses the third hire."""
|
|
async with session_factory() as session:
|
|
grants = FakeGrants({world.fast_id: "fast"}, policy=DefaultOrgPolicy(max_employees=2))
|
|
manager = await _manager(world, session, scripted=ScriptedModel(), grants=grants)
|
|
await _hire_tester(manager, world)
|
|
await _hire_tester(manager, world)
|
|
with pytest.raises(ConflictError, match=r"\(2\)"):
|
|
await _hire_tester(manager, world)
|
|
|
|
|
|
async def test_the_global_cap_still_wins_when_it_is_lower(world, session_factory, monkeypatch):
|
|
"""The owner can tighten the cap, but a policy of 5 does not lift a global cap of 1."""
|
|
monkeypatch.setattr(settings, "engine_max_employees", 1)
|
|
async with session_factory() as session:
|
|
grants = FakeGrants({world.fast_id: "fast"}, policy=DefaultOrgPolicy(max_employees=5))
|
|
manager = await _manager(world, session, scripted=ScriptedModel(), grants=grants)
|
|
await _hire_tester(manager, world)
|
|
with pytest.raises(ConflictError, match=r"\(1\)"):
|
|
await _hire_tester(manager, world)
|
|
|
|
|
|
async def test_a_fired_employee_frees_a_hire_slot(world, session_factory):
|
|
"""At the cap, firing one employee archives them, and the next hire succeeds."""
|
|
async with session_factory() as session:
|
|
grants = FakeGrants({world.fast_id: "fast"}, policy=DefaultOrgPolicy(max_employees=2))
|
|
manager = await _manager(world, session, scripted=ScriptedModel(), grants=grants)
|
|
first = await _hire_tester(manager, world)
|
|
await _hire_tester(manager, world)
|
|
with pytest.raises(ConflictError, match=r"\(2\)"):
|
|
await _hire_tester(manager, world)
|
|
await manager.fire(organization_id=world.organization_id, employee_id=first.id)
|
|
await session.commit()
|
|
|
|
replacement = await _hire_tester(manager, world)
|
|
await session.commit()
|
|
headcount = await EmployeeRepository(session).count_for_org(world.organization_id)
|
|
|
|
assert replacement.role_key is RoleKey.TESTER
|
|
assert headcount == 2
|