@@ -913,3 +913,63 @@ func Test_PullRequestRead_FieldsPreserveIFCLabel(t *testing.T) {
913913 assert .Equal (t , "public" , ifcMap ["confidentiality" ])
914914 })
915915}
916+
917+ // Test_PullRequestRead_FieldsAfterLockdown proves that lockdown/security
918+ // filtering and response field filtering compose in the required order on a
919+ // single call: disallowed reviews are dropped first, then the surviving review
920+ // is trimmed to the requested fields.
921+ func Test_PullRequestRead_FieldsAfterLockdown (t * testing.T ) {
922+ serverTool := PullRequestRead (translations .NullTranslationHelper )
923+
924+ reviews := []* github.PullRequestReview {
925+ {
926+ ID : github .Ptr (int64 (2030 )),
927+ State : github .Ptr ("APPROVED" ),
928+ Body : github .Ptr ("Maintainer review" ),
929+ User : & github.User {Login : github .Ptr ("maintainer" )},
930+ },
931+ {
932+ ID : github .Ptr (int64 (2031 )),
933+ State : github .Ptr ("COMMENTED" ),
934+ Body : github .Ptr ("External reviewer" ),
935+ User : & github.User {Login : github .Ptr ("testuser" )},
936+ },
937+ }
938+
939+ client := mustNewGHClient (t , MockHTTPClientWithHandlers (map [string ]http.HandlerFunc {
940+ GetReposPullsReviewsByOwnerByRepoByPullNumber : mockResponse (t , http .StatusOK , reviews ),
941+ }))
942+ restClient := mockRESTPermissionServer (t , "read" , map [string ]string {
943+ "maintainer" : "write" ,
944+ "testuser" : "read" ,
945+ })
946+
947+ deps := BaseDeps {
948+ Client : client ,
949+ RepoAccessCache : stubRepoAccessCache (restClient , 5 * time .Minute ),
950+ Flags : stubFeatureFlags (map [string ]bool {"lockdown-mode" : true }),
951+ }
952+ handler := serverTool .Handler (deps )
953+
954+ request := createMCPRequest (map [string ]any {
955+ "method" : "get_reviews" ,
956+ "owner" : "owner" ,
957+ "repo" : "repo" ,
958+ "pullNumber" : float64 (42 ),
959+ "fields" : []any {"state" },
960+ })
961+ result , err := handler (ContextWithDeps (context .Background (), deps ), & request )
962+ require .NoError (t , err )
963+ require .False (t , result .IsError )
964+
965+ var returned []map [string ]any
966+ require .NoError (t , json .Unmarshal ([]byte (getTextResult (t , result ).Text ), & returned ))
967+
968+ // Lockdown dropped the external reviewer (read-only permission).
969+ require .Len (t , returned , 1 )
970+ // Field filtering then kept only `state` on the survivor.
971+ require .Len (t , returned [0 ], 1 )
972+ assert .Equal (t , "APPROVED" , returned [0 ]["state" ])
973+ assert .NotContains (t , returned [0 ], "body" )
974+ assert .NotContains (t , returned [0 ], "id" )
975+ }
0 commit comments