@@ -2,6 +2,7 @@ package buildkite
22
33import (
44 "context"
5+ "errors"
56 "net/http"
67 "testing"
78
@@ -14,6 +15,8 @@ type MockBuildsClient struct {
1415 ListByPipelineFunc func (ctx context.Context , org string , pipeline string , opt * buildkite.BuildsListOptions ) ([]buildkite.Build , * buildkite.Response , error )
1516 GetFunc func (ctx context.Context , org string , pipeline string , id string , opt * buildkite.BuildGetOptions ) (buildkite.Build , * buildkite.Response , error )
1617 CreateFunc func (ctx context.Context , org string , pipeline string , b buildkite.CreateBuild ) (buildkite.Build , * buildkite.Response , error )
18+ CancelFunc func (ctx context.Context , org , pipeline , buildNumber string ) (buildkite.Build , error )
19+ RebuildFunc func (ctx context.Context , org , pipeline , buildNumber string ) (buildkite.Build , error )
1720}
1821
1922func (m * MockBuildsClient ) Get (ctx context.Context , org string , pipeline string , id string , opt * buildkite.BuildGetOptions ) (buildkite.Build , * buildkite.Response , error ) {
@@ -44,6 +47,20 @@ func (m *MockBuildsClient) Create(ctx context.Context, org string, pipeline stri
4447 return buildkite.Build {}, nil , nil
4548}
4649
50+ func (m * MockBuildsClient ) Cancel (ctx context.Context , org , pipeline , buildNumber string ) (buildkite.Build , error ) {
51+ if m .CancelFunc != nil {
52+ return m .CancelFunc (ctx , org , pipeline , buildNumber )
53+ }
54+ return buildkite.Build {}, nil
55+ }
56+
57+ func (m * MockBuildsClient ) Rebuild (ctx context.Context , org , pipeline , buildNumber string ) (buildkite.Build , error ) {
58+ if m .RebuildFunc != nil {
59+ return m .RebuildFunc (ctx , org , pipeline , buildNumber )
60+ }
61+ return buildkite.Build {}, nil
62+ }
63+
4764var _ BuildsClient = (* MockBuildsClient )(nil )
4865
4966func TestGetBuildDefault (t * testing.T ) {
@@ -757,3 +774,129 @@ func TestGetBuildInvalidDetailLevel(t *testing.T) {
757774 textContent := getTextResult (t , result )
758775 assert .Contains (textContent .Text , "detail_level must be 'detailed' or 'full'" )
759776}
777+
778+ func TestCancelBuild (t * testing.T ) {
779+ t .Run ("ToolDefinition" , func (t * testing.T ) {
780+ tool , _ , _ := CancelBuild ()
781+ require .Equal (t , "cancel_build" , tool .Name )
782+ require .Contains (t , tool .Description , "Cancel" )
783+ })
784+
785+ t .Run ("Success" , func (t * testing.T ) {
786+ assert := require .New (t )
787+
788+ client := & MockBuildsClient {
789+ CancelFunc : func (ctx context.Context , org , pipeline , buildNumber string ) (buildkite.Build , error ) {
790+ assert .Equal ("test-org" , org )
791+ assert .Equal ("test-pipeline" , pipeline )
792+ assert .Equal ("42" , buildNumber )
793+ return buildkite.Build {
794+ ID : "123" ,
795+ Number : 42 ,
796+ State : "canceling" ,
797+ }, nil
798+ },
799+ }
800+
801+ ctx := ContextWithDeps (context .Background (), ToolDependencies {BuildsClient : client })
802+ _ , handler , _ := CancelBuild ()
803+
804+ result , _ , err := handler (ctx , createMCPRequest (t , map [string ]any {}), CancelBuildArgs {
805+ OrgSlug : "test-org" ,
806+ PipelineSlug : "test-pipeline" ,
807+ BuildNumber : "42" ,
808+ })
809+ assert .NoError (err )
810+
811+ textContent := getTextResult (t , result )
812+ assert .Contains (textContent .Text , `"id":"123"` )
813+ assert .Contains (textContent .Text , `"state":"canceling"` )
814+ })
815+
816+ t .Run ("Error" , func (t * testing.T ) {
817+ assert := require .New (t )
818+
819+ client := & MockBuildsClient {
820+ CancelFunc : func (ctx context.Context , org , pipeline , buildNumber string ) (buildkite.Build , error ) {
821+ return buildkite.Build {}, errors .New ("build not found" )
822+ },
823+ }
824+
825+ ctx := ContextWithDeps (context .Background (), ToolDependencies {BuildsClient : client })
826+ _ , handler , _ := CancelBuild ()
827+
828+ result , _ , err := handler (ctx , createMCPRequest (t , map [string ]any {}), CancelBuildArgs {
829+ OrgSlug : "test-org" ,
830+ PipelineSlug : "test-pipeline" ,
831+ BuildNumber : "42" ,
832+ })
833+ assert .NoError (err )
834+ assert .True (result .IsError )
835+
836+ textContent := getTextResult (t , result )
837+ assert .Contains (textContent .Text , "build not found" )
838+ })
839+ }
840+
841+ func TestRebuildBuild (t * testing.T ) {
842+ t .Run ("ToolDefinition" , func (t * testing.T ) {
843+ tool , _ , _ := RebuildBuild ()
844+ require .Equal (t , "rebuild_build" , tool .Name )
845+ require .Contains (t , tool .Description , "Rebuild" )
846+ })
847+
848+ t .Run ("Success" , func (t * testing.T ) {
849+ assert := require .New (t )
850+
851+ client := & MockBuildsClient {
852+ RebuildFunc : func (ctx context.Context , org , pipeline , buildNumber string ) (buildkite.Build , error ) {
853+ assert .Equal ("test-org" , org )
854+ assert .Equal ("test-pipeline" , pipeline )
855+ assert .Equal ("42" , buildNumber )
856+ return buildkite.Build {
857+ ID : "456" ,
858+ Number : 43 ,
859+ State : "scheduled" ,
860+ }, nil
861+ },
862+ }
863+
864+ ctx := ContextWithDeps (context .Background (), ToolDependencies {BuildsClient : client })
865+ _ , handler , _ := RebuildBuild ()
866+
867+ result , _ , err := handler (ctx , createMCPRequest (t , map [string ]any {}), RebuildBuildArgs {
868+ OrgSlug : "test-org" ,
869+ PipelineSlug : "test-pipeline" ,
870+ BuildNumber : "42" ,
871+ })
872+ assert .NoError (err )
873+
874+ textContent := getTextResult (t , result )
875+ assert .Contains (textContent .Text , `"id":"456"` )
876+ assert .Contains (textContent .Text , `"state":"scheduled"` )
877+ })
878+
879+ t .Run ("Error" , func (t * testing.T ) {
880+ assert := require .New (t )
881+
882+ client := & MockBuildsClient {
883+ RebuildFunc : func (ctx context.Context , org , pipeline , buildNumber string ) (buildkite.Build , error ) {
884+ return buildkite.Build {}, errors .New ("build not found" )
885+ },
886+ }
887+
888+ ctx := ContextWithDeps (context .Background (), ToolDependencies {BuildsClient : client })
889+ _ , handler , _ := RebuildBuild ()
890+
891+ result , _ , err := handler (ctx , createMCPRequest (t , map [string ]any {}), RebuildBuildArgs {
892+ OrgSlug : "test-org" ,
893+ PipelineSlug : "test-pipeline" ,
894+ BuildNumber : "42" ,
895+ })
896+ assert .NoError (err )
897+ assert .True (result .IsError )
898+
899+ textContent := getTextResult (t , result )
900+ assert .Contains (textContent .Text , "build not found" )
901+ })
902+ }
0 commit comments