@@ -59,6 +59,10 @@ type bootstrapRuntimeStub struct {
5959 checkpointDiffFn func (ctx context.Context , input CheckpointDiffInput ) (CheckpointDiffResult , error )
6060}
6161
62+ type runtimePortWithoutPlanApproval struct {
63+ RuntimePort
64+ }
65+
6266func (s * bootstrapRuntimeStub ) Run (ctx context.Context , input RunInput ) error {
6367 if s != nil && s .runFn != nil {
6468 return s .runFn (ctx , input )
@@ -2630,6 +2634,86 @@ func TestHandleCancelListLoadResolveBranches(t *testing.T) {
26302634 }
26312635 })
26322636
2637+ t .Run ("approve plan runtime unavailable" , func (t * testing.T ) {
2638+ response := handleApprovePlanFrame (context .Background (), MessageFrame {
2639+ Type : FrameTypeRequest ,
2640+ Action : FrameActionApprovePlan ,
2641+ Payload : map [string ]any {
2642+ "session_id" : "session-1" ,
2643+ "plan_id" : "plan-1" ,
2644+ "revision" : 1 ,
2645+ },
2646+ }, nil )
2647+ if response .Type != FrameTypeError {
2648+ t .Fatalf ("response type = %q, want %q" , response .Type , FrameTypeError )
2649+ }
2650+ if response .Error == nil || response .Error .Code != ErrorCodeInternalError .String () {
2651+ t .Fatalf ("response error = %#v, want %q" , response .Error , ErrorCodeInternalError .String ())
2652+ }
2653+ })
2654+
2655+ t .Run ("approve plan unsupported runtime port" , func (t * testing.T ) {
2656+ response := handleApprovePlanFrame (context .Background (), MessageFrame {
2657+ Type : FrameTypeRequest ,
2658+ Action : FrameActionApprovePlan ,
2659+ Payload : map [string ]any {
2660+ "session_id" : "session-1" ,
2661+ "plan_id" : "plan-1" ,
2662+ "revision" : 1 ,
2663+ },
2664+ }, runtimePortWithoutPlanApproval {RuntimePort : & bootstrapRuntimeStub {}})
2665+ if response .Type != FrameTypeError {
2666+ t .Fatalf ("response type = %q, want %q" , response .Type , FrameTypeError )
2667+ }
2668+ if response .Error == nil || response .Error .Code != ErrorCodeInternalError .String () {
2669+ t .Fatalf ("response error = %#v, want %q" , response .Error , ErrorCodeInternalError .String ())
2670+ }
2671+ })
2672+
2673+ t .Run ("approve plan fills session from frame" , func (t * testing.T ) {
2674+ stub := & bootstrapRuntimeStub {
2675+ approvePlanFn : func (_ context.Context , input ApprovePlanInput ) (ApprovePlanResult , error ) {
2676+ if input .SessionID != "session-from-frame" {
2677+ t .Fatalf ("session_id = %q, want frame session" , input .SessionID )
2678+ }
2679+ return ApprovePlanResult {PlanID : input .PlanID , Revision : input .Revision , Status : "approved" }, nil
2680+ },
2681+ }
2682+ response := handleApprovePlanFrame (context .Background (), MessageFrame {
2683+ Type : FrameTypeRequest ,
2684+ Action : FrameActionApprovePlan ,
2685+ SessionID : " session-from-frame " ,
2686+ Payload : map [string ]any {
2687+ "plan_id" : "plan-1" ,
2688+ "revision" : 1 ,
2689+ },
2690+ }, stub )
2691+ if response .Type != FrameTypeAck {
2692+ t .Fatalf ("response = %#v, want ack" , response )
2693+ }
2694+ if response .SessionID != "session-from-frame" {
2695+ t .Fatalf ("response session_id = %q, want frame session" , response .SessionID )
2696+ }
2697+ })
2698+
2699+ t .Run ("approve plan invalid revision" , func (t * testing.T ) {
2700+ response := handleApprovePlanFrame (context .Background (), MessageFrame {
2701+ Type : FrameTypeRequest ,
2702+ Action : FrameActionApprovePlan ,
2703+ Payload : map [string ]any {
2704+ "session_id" : "session-1" ,
2705+ "plan_id" : "plan-1" ,
2706+ "revision" : 0 ,
2707+ },
2708+ }, & bootstrapRuntimeStub {})
2709+ if response .Type != FrameTypeError {
2710+ t .Fatalf ("response type = %q, want %q" , response .Type , FrameTypeError )
2711+ }
2712+ if response .Error == nil || response .Error .Code != ErrorCodeInvalidAction .String () {
2713+ t .Fatalf ("response error = %#v, want %q" , response .Error , ErrorCodeInvalidAction .String ())
2714+ }
2715+ })
2716+
26332717 t .Run ("approve plan success" , func (t * testing.T ) {
26342718 stub := & bootstrapRuntimeStub {
26352719 approvePlanFn : func (ctx context.Context , input ApprovePlanInput ) (ApprovePlanResult , error ) {
0 commit comments