|
| 1 | +import json |
1 | 2 | import types |
2 | 3 |
|
3 | 4 | from application.cycle_result import StrategyCycleResult |
@@ -29,6 +30,35 @@ def test_health_route_returns_ok(strategy_module): |
29 | 30 | assert body == "OK" |
30 | 31 |
|
31 | 32 |
|
| 33 | +def test_platform_notification_prefix_stays_empty_for_default_account(strategy_module): |
| 34 | + assert strategy_module._platform_notification_prefix() == "" |
| 35 | + assert strategy_module._with_platform_notification_prefix("hello") == "hello" |
| 36 | + |
| 37 | + |
| 38 | +def test_platform_notification_prefix_uses_ibkr_account_scope(strategy_module_factory): |
| 39 | + module = strategy_module_factory( |
| 40 | + ACCOUNT_GROUP="live-u1234567", |
| 41 | + IB_ACCOUNT_GROUP_CONFIG_JSON=( |
| 42 | + '{"groups":{"live-u1234567":{"ib_gateway_instance_name":"127.0.0.1",' |
| 43 | + '"ib_gateway_mode":"live","ib_client_id":1,"account_ids":["U1234567"]}}}' |
| 44 | + ), |
| 45 | + RUNTIME_TARGET_JSON=json.dumps( |
| 46 | + { |
| 47 | + "platform_id": "ibkr", |
| 48 | + "strategy_profile": "global_etf_rotation", |
| 49 | + "dry_run_only": False, |
| 50 | + "execution_mode": "live", |
| 51 | + "account_selector": ["U1234567"], |
| 52 | + "account_scope": "live-u1234567", |
| 53 | + }, |
| 54 | + separators=(",", ":"), |
| 55 | + ), |
| 56 | + ) |
| 57 | + |
| 58 | + assert module._platform_notification_prefix() == "[U1234567]" |
| 59 | + assert module._with_platform_notification_prefix("hello") == "[U1234567] hello" |
| 60 | + |
| 61 | + |
32 | 62 | def test_handle_request_get_returns_safe_message(strategy_module, monkeypatch): |
33 | 63 | def fail_if_called(): |
34 | 64 | raise AssertionError("GET should not execute strategy") |
@@ -755,3 +785,45 @@ def fake_post(_url, *, json, timeout): |
755 | 785 | assert "IBKR 策略运行失败" in text |
756 | 786 | assert "账户组:" in text |
757 | 787 | assert "错误: RuntimeError: boom" in text |
| 788 | + |
| 789 | + |
| 790 | +def test_handle_request_runtime_error_fallback_prefixes_account_scope(strategy_module_factory, monkeypatch): |
| 791 | + strategy_module = strategy_module_factory( |
| 792 | + ACCOUNT_GROUP="live-u1234567", |
| 793 | + IB_ACCOUNT_GROUP_CONFIG_JSON=( |
| 794 | + '{"groups":{"live-u1234567":{"ib_gateway_instance_name":"127.0.0.1",' |
| 795 | + '"ib_gateway_mode":"live","ib_client_id":1,"account_ids":["U1234567"]}}}' |
| 796 | + ), |
| 797 | + RUNTIME_TARGET_JSON=json.dumps( |
| 798 | + { |
| 799 | + "platform_id": "ibkr", |
| 800 | + "strategy_profile": "global_etf_rotation", |
| 801 | + "dry_run_only": False, |
| 802 | + "execution_mode": "live", |
| 803 | + "account_selector": ["U1234567"], |
| 804 | + "account_scope": "live-u1234567", |
| 805 | + }, |
| 806 | + separators=(",", ":"), |
| 807 | + ), |
| 808 | + ) |
| 809 | + sent_payloads = [] |
| 810 | + |
| 811 | + class FakeResponse: |
| 812 | + status_code = 200 |
| 813 | + text = "ok" |
| 814 | + |
| 815 | + def fake_post(_url, *, json, timeout): |
| 816 | + sent_payloads.append((json, timeout)) |
| 817 | + return FakeResponse() |
| 818 | + |
| 819 | + monkeypatch.setattr(strategy_module, "_handle_request", lambda: (_ for _ in ()).throw(RuntimeError("boom"))) |
| 820 | + monkeypatch.setattr(strategy_module, "TG_TOKEN", "token-1") |
| 821 | + monkeypatch.setattr(strategy_module, "TG_CHAT_ID", "chat-1") |
| 822 | + monkeypatch.setattr(strategy_module.requests, "post", fake_post) |
| 823 | + |
| 824 | + with strategy_module.app.test_request_context("/run", method="POST"): |
| 825 | + body, status = strategy_module.handle_request() |
| 826 | + |
| 827 | + assert status == 500 |
| 828 | + assert body == "Error" |
| 829 | + assert sent_payloads[0][0]["text"].startswith("[U1234567] IBKR strategy run failed") |
0 commit comments