@@ -1565,3 +1565,33 @@ def test_handle_reconciliation_rejects_missing_scheduler_identity_before_broker_
15651565
15661566 assert (body , response_code ) == ("Error" , 400 )
15671567 assert broker_connection_attempts == []
1568+
1569+
1570+ @pytest .mark .parametrize (
1571+ ("scheduler_identity" , "reason" ),
1572+ [
1573+ (None , "missing_scheduler_identity" ),
1574+ ("" , "invalid_scheduler_identity" ),
1575+ ("private-invalid-header-value" , "invalid_scheduler_identity" ),
1576+ ],
1577+ )
1578+ def test_reconciliation_rejection_reports_only_safe_reason (
1579+ strategy_module , monkeypatch , capsys , scheduler_identity , reason ,
1580+ ):
1581+ def forbidden (* _args , ** _kwargs ):
1582+ raise AssertionError ("rejected request must not read broker or persist report" )
1583+
1584+ for name in ("connect_ib" , "build_execution_report" , "persist_reconciliation_report" ):
1585+ monkeypatch .setattr (strategy_module , name , forbidden )
1586+ headers = {} if scheduler_identity is None else {"X-CloudScheduler-JobName" : scheduler_identity }
1587+ capsys .readouterr ()
1588+ response = strategy_module .app .test_client ().post ("/reconcile" , headers = headers )
1589+
1590+ assert response .status_code == 400
1591+ assert response .get_data (as_text = True ) == "Error"
1592+ output = capsys .readouterr ()
1593+ assert json .loads (output .out ) == {
1594+ "event" : "broker_reconciliation_rejected" ,
1595+ "reason" : reason ,
1596+ }
1597+ assert output .err == ""
0 commit comments