@@ -1170,3 +1170,146 @@ func Test_mergeHeaderMutations(t *testing.T) {
11701170 })
11711171 }
11721172}
1173+
1174+ func Test_mergeBodyMutations (t * testing.T ) {
1175+ tests := []struct {
1176+ name string
1177+ routeLevel * aigv1a1.HTTPBodyMutation
1178+ backendLevel * aigv1a1.HTTPBodyMutation
1179+ expected * aigv1a1.HTTPBodyMutation
1180+ }{
1181+ {
1182+ name : "both nil" ,
1183+ routeLevel : nil ,
1184+ backendLevel : nil ,
1185+ expected : nil ,
1186+ },
1187+ {
1188+ name : "route nil, backend has values" ,
1189+ routeLevel : nil ,
1190+ backendLevel : & aigv1a1.HTTPBodyMutation {
1191+ Set : []aigv1a1.HTTPBodyField {{Path : "backend_field" , Value : "backend-value" }},
1192+ Remove : []string {"backend_remove" },
1193+ },
1194+ expected : & aigv1a1.HTTPBodyMutation {
1195+ Set : []aigv1a1.HTTPBodyField {{Path : "backend_field" , Value : "backend-value" }},
1196+ Remove : []string {"backend_remove" },
1197+ },
1198+ },
1199+ {
1200+ name : "route has values, backend nil" ,
1201+ routeLevel : & aigv1a1.HTTPBodyMutation {
1202+ Set : []aigv1a1.HTTPBodyField {{Path : "route_field" , Value : "route-value" }},
1203+ Remove : []string {"route_remove" },
1204+ },
1205+ backendLevel : nil ,
1206+ expected : & aigv1a1.HTTPBodyMutation {
1207+ Set : []aigv1a1.HTTPBodyField {{Path : "route_field" , Value : "route-value" }},
1208+ Remove : []string {"route_remove" },
1209+ },
1210+ },
1211+ {
1212+ name : "no conflicts - different fields" ,
1213+ routeLevel : & aigv1a1.HTTPBodyMutation {
1214+ Set : []aigv1a1.HTTPBodyField {{Path : "route_field" , Value : "route-value" }},
1215+ Remove : []string {"route_remove" },
1216+ },
1217+ backendLevel : & aigv1a1.HTTPBodyMutation {
1218+ Set : []aigv1a1.HTTPBodyField {{Path : "backend_field" , Value : "backend-value" }},
1219+ Remove : []string {"backend_remove" },
1220+ },
1221+ expected : & aigv1a1.HTTPBodyMutation {
1222+ Set : []aigv1a1.HTTPBodyField {
1223+ {Path : "backend_field" , Value : "backend-value" },
1224+ {Path : "route_field" , Value : "route-value" },
1225+ },
1226+ Remove : []string {"backend_remove" , "route_remove" },
1227+ },
1228+ },
1229+ {
1230+ name : "route overrides backend for same field path" ,
1231+ routeLevel : & aigv1a1.HTTPBodyMutation {
1232+ Set : []aigv1a1.HTTPBodyField {{Path : "service_tier" , Value : "route-value" }},
1233+ },
1234+ backendLevel : & aigv1a1.HTTPBodyMutation {
1235+ Set : []aigv1a1.HTTPBodyField {{Path : "service_tier" , Value : "backend-value" }},
1236+ },
1237+ expected : & aigv1a1.HTTPBodyMutation {
1238+ Set : []aigv1a1.HTTPBodyField {{Path : "service_tier" , Value : "route-value" }},
1239+ },
1240+ },
1241+ {
1242+ name : "remove operations are combined and deduplicated" ,
1243+ routeLevel : & aigv1a1.HTTPBodyMutation {
1244+ Remove : []string {"field1" , "shared_field" },
1245+ },
1246+ backendLevel : & aigv1a1.HTTPBodyMutation {
1247+ Remove : []string {"field2" , "shared_field" },
1248+ },
1249+ expected : & aigv1a1.HTTPBodyMutation {
1250+ Remove : []string {"field1" , "field2" , "shared_field" },
1251+ },
1252+ },
1253+ {
1254+ name : "complex merge scenario" ,
1255+ routeLevel : & aigv1a1.HTTPBodyMutation {
1256+ Set : []aigv1a1.HTTPBodyField {
1257+ {Path : "route_only" , Value : "route-only" },
1258+ {Path : "override_field" , Value : "route-wins" },
1259+ },
1260+ Remove : []string {"route_remove" , "shared_remove" },
1261+ },
1262+ backendLevel : & aigv1a1.HTTPBodyMutation {
1263+ Set : []aigv1a1.HTTPBodyField {
1264+ {Path : "backend_only" , Value : "backend-only" },
1265+ {Path : "override_field" , Value : "backend-loses" },
1266+ },
1267+ Remove : []string {"backend_remove" , "shared_remove" },
1268+ },
1269+ expected : & aigv1a1.HTTPBodyMutation {
1270+ Set : []aigv1a1.HTTPBodyField {
1271+ {Path : "backend_only" , Value : "backend-only" },
1272+ {Path : "override_field" , Value : "route-wins" },
1273+ {Path : "route_only" , Value : "route-only" },
1274+ },
1275+ Remove : []string {"backend_remove" , "route_remove" , "shared_remove" },
1276+ },
1277+ },
1278+ {
1279+ name : "empty mutations" ,
1280+ routeLevel : & aigv1a1.HTTPBodyMutation {
1281+ Set : []aigv1a1.HTTPBodyField {},
1282+ Remove : []string {},
1283+ },
1284+ backendLevel : & aigv1a1.HTTPBodyMutation {
1285+ Set : []aigv1a1.HTTPBodyField {},
1286+ Remove : []string {},
1287+ },
1288+ expected : & aigv1a1.HTTPBodyMutation {
1289+ Set : nil ,
1290+ Remove : nil ,
1291+ },
1292+ },
1293+ }
1294+
1295+ for _ , tt := range tests {
1296+ t .Run (tt .name , func (t * testing.T ) {
1297+ result := mergeBodyMutations (tt .routeLevel , tt .backendLevel )
1298+
1299+ if tt .expected == nil {
1300+ require .Nil (t , result )
1301+ return
1302+ }
1303+
1304+ require .NotNil (t , result )
1305+
1306+ if d := cmp .Diff (tt .expected , result , cmpopts .SortSlices (func (a , b aigv1a1.HTTPBodyField ) bool {
1307+ return a .Path < b .Path
1308+ }), cmpopts .SortSlices (func (a , b string ) bool {
1309+ return a < b
1310+ })); d != "" {
1311+ t .Errorf ("mergeBodyMutations() mismatch (-expected +got):\n %s" , d )
1312+ }
1313+ })
1314+ }
1315+ }
0 commit comments