@@ -987,3 +987,267 @@ func createHealeniumMockServerByParameters(
987987 }
988988 }))
989989}
990+
991+ // TestUpdateHealingResultTool_Integration tests the complete flow of updateHealingResultTool
992+ // Architecture:
993+ // LLM Mock Client -> Healenium MCP Server -> Healenium Server Mock
994+ func TestUpdateHealingResultTool_Integration (t * testing.T ) {
995+ tests := []struct {
996+ name string
997+ healingResultId float64
998+ successHealing bool
999+ healeniumStatusCode int
1000+ expectedSuccess bool
1001+ expectedErrorContent string
1002+ expectedMessage string
1003+ }{
1004+ {
1005+ name : "successful healing update" ,
1006+ healingResultId : float64 (68 ),
1007+ successHealing : true ,
1008+ healeniumStatusCode : http .StatusOK ,
1009+ expectedSuccess : true ,
1010+ expectedMessage : "Healing result 68 updated successfully as successful (HTTP 200)" ,
1011+ },
1012+ {
1013+ name : "failed healing update" ,
1014+ healingResultId : float64 (69 ),
1015+ successHealing : false ,
1016+ healeniumStatusCode : http .StatusOK ,
1017+ expectedSuccess : true ,
1018+ expectedMessage : "Healing result 69 updated successfully as failed (HTTP 200)" ,
1019+ },
1020+ {
1021+ name : "server error" ,
1022+ healingResultId : float64 (70 ),
1023+ successHealing : true ,
1024+ healeniumStatusCode : http .StatusInternalServerError ,
1025+ expectedSuccess : false ,
1026+ expectedErrorContent : "failed to update healing result" ,
1027+ },
1028+ {
1029+ name : "not found error" ,
1030+ healingResultId : float64 (999 ),
1031+ successHealing : true ,
1032+ healeniumStatusCode : http .StatusNotFound ,
1033+ expectedSuccess : false ,
1034+ expectedErrorContent : "failed to update healing result" ,
1035+ },
1036+ {
1037+ name : "bad request error" ,
1038+ healingResultId : float64 (0 ),
1039+ successHealing : true ,
1040+ healeniumStatusCode : http .StatusBadRequest ,
1041+ expectedSuccess : false ,
1042+ expectedErrorContent : "failed to update healing result" ,
1043+ },
1044+ }
1045+
1046+ for _ , tt := range tests {
1047+ t .Run (tt .name , func (t * testing.T ) {
1048+ // Step 1: Create mock Healenium server
1049+ mockHealeniumServer := createMockUpdateHealingResultServer (
1050+ t ,
1051+ tt .healingResultId ,
1052+ tt .successHealing ,
1053+ tt .healeniumStatusCode ,
1054+ )
1055+ defer mockHealeniumServer .Close ()
1056+
1057+ // Step 2: Create Healenium MCP Server pointing to the mock backend
1058+ healeniumMcpServer := createHealeniumMCPServer (t , mockHealeniumServer .URL )
1059+
1060+ // Step 3: Call the tool handler
1061+ _ , handler := healeniumMcpServer .updateHealingResultTool ()
1062+ ctx := context .Background ()
1063+ req := & mcp.CallToolRequest {}
1064+ input := map [string ]any {
1065+ "healingResultId" : tt .healingResultId ,
1066+ "successHealing" : tt .successHealing ,
1067+ }
1068+
1069+ result , _ , err := handler (ctx , req , input )
1070+
1071+ // Step 4: Verify results
1072+ if tt .expectedSuccess {
1073+ if err != nil {
1074+ t .Errorf ("expected success but got error: %v" , err )
1075+ }
1076+ if result == nil {
1077+ t .Fatal ("expected result but got nil" )
1078+ }
1079+ if len (result .Content ) == 0 {
1080+ t .Fatal ("expected content but got empty array" )
1081+ }
1082+
1083+ // Check the success message
1084+ textContent , ok := result .Content [0 ].(* mcp.TextContent )
1085+ if ! ok {
1086+ t .Errorf ("expected TextContent but got different type" )
1087+ } else if ! strings .Contains (textContent .Text , tt .expectedMessage ) {
1088+ t .Errorf ("expected message to contain %q but got %q" , tt .expectedMessage , textContent .Text )
1089+ }
1090+ } else {
1091+ if err == nil {
1092+ t .Error ("expected error but got success" )
1093+ } else if ! contains (err .Error (), tt .expectedErrorContent ) {
1094+ t .Errorf ("expected error to contain %q but got %q" , tt .expectedErrorContent , err .Error ())
1095+ }
1096+ }
1097+ })
1098+ }
1099+ }
1100+
1101+ // TestUpdateHealingResultTool_ValidationErrors tests parameter validation
1102+ func TestUpdateHealingResultTool_ValidationErrors (t * testing.T ) {
1103+ tests := []struct {
1104+ name string
1105+ input map [string ]any
1106+ expectedErrorContent string
1107+ }{
1108+ {
1109+ name : "missing healingResultId" ,
1110+ input : map [string ]any {
1111+ "successHealing" : true ,
1112+ },
1113+ expectedErrorContent : "healingResultId is required and must be an unsigned integer" ,
1114+ },
1115+ {
1116+ name : "missing successHealing" ,
1117+ input : map [string ]any {
1118+ "healingResultId" : float64 (68 ),
1119+ },
1120+ expectedErrorContent : "successHealing is required and must be a boolean" ,
1121+ },
1122+ {
1123+ name : "invalid healingResultId type - string" ,
1124+ input : map [string ]any {
1125+ "healingResultId" : "not a number" ,
1126+ "successHealing" : true ,
1127+ },
1128+ expectedErrorContent : "healingResultId is required and must be an unsigned integer" ,
1129+ },
1130+ {
1131+ name : "invalid successHealing type - string" ,
1132+ input : map [string ]any {
1133+ "healingResultId" : float64 (68 ),
1134+ "successHealing" : "not a boolean" ,
1135+ },
1136+ expectedErrorContent : "successHealing is required and must be a boolean" ,
1137+ },
1138+ {
1139+ name : "negative healingResultId" ,
1140+ input : map [string ]any {
1141+ "healingResultId" : float64 (- 1 ),
1142+ "successHealing" : true ,
1143+ },
1144+ expectedErrorContent : "healingResultId must be a non-negative integer" ,
1145+ },
1146+ {
1147+ name : "fractional healingResultId" ,
1148+ input : map [string ]any {
1149+ "healingResultId" : float64 (68.5 ),
1150+ "successHealing" : true ,
1151+ },
1152+ expectedErrorContent : "healingResultId must be a non-negative integer" ,
1153+ },
1154+ }
1155+
1156+ for _ , tt := range tests {
1157+ t .Run (tt .name , func (t * testing.T ) {
1158+ // Create MCP tool with dummy client
1159+ client := resty .New ().SetBaseURL ("http://dummy" )
1160+ mcpTool := newMcpTool (client , nil )
1161+
1162+ _ , handler := mcpTool .updateHealingResultTool ()
1163+ ctx := context .Background ()
1164+ req := & mcp.CallToolRequest {}
1165+
1166+ _ , _ , err := handler (ctx , req , tt .input )
1167+ if err == nil {
1168+ t .Fatal ("expected error but got nil" )
1169+ }
1170+ if ! contains (err .Error (), tt .expectedErrorContent ) {
1171+ t .Errorf (
1172+ "expected error to contain %q but got %q" ,
1173+ tt .expectedErrorContent ,
1174+ err .Error (),
1175+ )
1176+ }
1177+ })
1178+ }
1179+ }
1180+
1181+ // TestUpdateHealingResultTool_Timeout tests timeout behavior
1182+ func TestUpdateHealingResultTool_Timeout (t * testing.T ) {
1183+ // Create a mock Healenium server that delays response
1184+ healeniumServerMock := httptest .NewServer (
1185+ http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1186+ // Delay response to trigger timeout
1187+ time .Sleep (2 * time .Second )
1188+ w .WriteHeader (http .StatusOK )
1189+ }),
1190+ )
1191+ defer healeniumServerMock .Close ()
1192+
1193+ // Create MCP server with short timeout
1194+ healeniumURL , _ := url .Parse (healeniumServerMock .URL )
1195+ client := resty .New ().
1196+ SetBaseURL (healeniumURL .String ()).
1197+ SetTimeout (500 * time .Millisecond ) // Short timeout
1198+
1199+ mcpTool := newMcpTool (client , nil )
1200+ _ , handler := mcpTool .updateHealingResultTool ()
1201+
1202+ // Call the tool
1203+ ctx := context .Background ()
1204+ req := & mcp.CallToolRequest {}
1205+ input := map [string ]any {
1206+ "healingResultId" : float64 (68 ),
1207+ "successHealing" : true ,
1208+ }
1209+
1210+ _ , _ , err := handler (ctx , req , input )
1211+ if err == nil {
1212+ t .Fatal ("expected timeout error but got nil" )
1213+ }
1214+
1215+ // Verify it's a timeout-related error
1216+ if ! contains (err .Error (), "failed to update healing result" ) {
1217+ t .Errorf ("expected timeout error but got: %v" , err )
1218+ }
1219+ }
1220+
1221+ // createMockUpdateHealingResultServer creates a mock Healenium server for testing updateHealingResult
1222+ func createMockUpdateHealingResultServer (
1223+ t * testing.T ,
1224+ expectedHealingResultId float64 ,
1225+ expectedSuccessHealing bool ,
1226+ statusCode int ,
1227+ ) * httptest.Server {
1228+ t .Helper ()
1229+
1230+ return httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1231+ // Verify the request is to the correct endpoint
1232+ if r .URL .Path != "/healenium/healing/success" {
1233+ t .Errorf ("expected path /healenium/healing/success but got %s" , r .URL .Path )
1234+ w .WriteHeader (http .StatusNotFound )
1235+ return
1236+ }
1237+
1238+ // Verify it's a POST request
1239+ if r .Method != http .MethodPost {
1240+ t .Errorf ("expected POST method but got %s" , r .Method )
1241+ w .WriteHeader (http .StatusMethodNotAllowed )
1242+ return
1243+ }
1244+
1245+ // Verify Content-Type
1246+ contentType := r .Header .Get ("Content-Type" )
1247+ if ! strings .Contains (contentType , "application/json" ) {
1248+ t .Errorf ("expected Content-Type to contain application/json but got %s" , contentType )
1249+ }
1250+
1251+ w .WriteHeader (statusCode )
1252+ }))
1253+ }
0 commit comments