import sys from pathlib import Path root = Path(__file__).resolve().parents[1] sys.path.insert(0, str(root)) sys.path.insert(0, str(root / 'packages' / 'agromatrix-tools')) from crews.agromatrix_crew import operator_commands as oc def test_parse(): cmd = oc.parse_operator_command('/pending --limit 5 --category field') assert cmd['cmd'] == 'pending' def test_gating(monkeypatch): monkeypatch.setenv('AGX_OPERATOR_IDS', '123') assert oc.is_operator('123', None) assert not oc.is_operator('999', None) def test_pending_list_flags(monkeypatch): monkeypatch.setenv('AGX_OPERATOR_IDS', '1') res = oc.route_operator_command('/pending --limit 5 --category unit', '1', None) assert res['status'] == 'ok' def test_approve_apply_guard(monkeypatch): monkeypatch.setenv('AGX_OPERATOR_IDS', '1') # no apply allowed by default res = oc.route_operator_command('/approve pending.jsonl:1 map_to crop_wheat_winter --apply', '1', None) assert res['summary'] == 'apply_not_allowed' def test_whoami_operator(monkeypatch): monkeypatch.setenv('AGX_OPERATOR_IDS', '1') res = oc.route_operator_command('/whoami', '1', '2') assert res['status'] == 'ok' assert 'user_id: 1' in res['summary'] assert 'chat_id: 2' in res['summary'] def test_whoami_non_operator(monkeypatch): monkeypatch.setenv('AGX_OPERATOR_IDS', '1') res = oc.route_operator_command('/whoami', '9', '2') assert res['status'] == 'error' def test_pending_show(monkeypatch): monkeypatch.setenv('AGX_OPERATOR_IDS', '1') def _fake_detail(_ref): return { 'ref': 'pending.jsonl:1', 'category': 'crop', 'raw_term': 'пшениця', 'ts': '2026-01-01T00:00:00Z', 'suggestions': [{'id': 'crop_wheat', 'score': 0.92}], 'status': 'approved', 'decision': 'approved', 'reason': 'match' } monkeypatch.setattr(oc.review, 'get_pending_detail', _fake_detail) res = oc.route_operator_command('/pending_show pending.jsonl:1', '1', None) assert res['status'] == 'ok' assert 'ref: pending.jsonl:1' in res['summary'] assert 'suggestions:' in res['summary']