@@ -289,6 +289,87 @@ public async Task ResourceMetadataEndpoint_ThrowsException_WhenNoMetadataProvide
289289 Assert . Equal ( HttpStatusCode . InternalServerError , response . StatusCode ) ;
290290 }
291291
292+ [ Fact ]
293+ public async Task ResourceMetadataEndpoint_HandlesResponse_WhenHandleResponseCalled ( )
294+ {
295+ Builder . Services . AddMcpServer ( ) . WithHttpTransport ( ) ;
296+
297+ // Override the configuration to test HandleResponse behavior
298+ Builder . Services . Configure < McpAuthenticationOptions > (
299+ McpAuthenticationDefaults . AuthenticationScheme ,
300+ options =>
301+ {
302+ options . ResourceMetadata = null ;
303+ options . Events . OnResourceMetadataRequest = async context =>
304+ {
305+ // Call HandleResponse() to discontinue processing and return to client
306+ context . HandleResponse ( ) ;
307+ await Task . CompletedTask ;
308+ } ;
309+ }
310+ ) ;
311+
312+ await using var app = Builder . Build ( ) ;
313+
314+ app . MapMcp ( ) . RequireAuthorization ( ) ;
315+
316+ await app . StartAsync ( TestContext . Current . CancellationToken ) ;
317+
318+ // Make a direct request to the resource metadata endpoint
319+ using var response = await HttpClient . GetAsync (
320+ "/.well-known/oauth-protected-resource" ,
321+ TestContext . Current . CancellationToken
322+ ) ;
323+
324+ // The request should be handled by the event handler without returning metadata
325+ // Since HandleResponse() was called, the handler should have taken responsibility
326+ // for generating the response, which in this case means an empty response
327+ Assert . Equal ( HttpStatusCode . OK , response . StatusCode ) ;
328+
329+ // The response should be empty since the event handler called HandleResponse()
330+ // but didn't write any content to the response
331+ var content = await response . Content . ReadAsStringAsync ( TestContext . Current . CancellationToken ) ;
332+ Assert . Empty ( content ) ;
333+ }
334+
335+ [ Fact ]
336+ public async Task ResourceMetadataEndpoint_SkipsHandler_WhenSkipHandlerCalled ( )
337+ {
338+ Builder . Services . AddMcpServer ( ) . WithHttpTransport ( ) ;
339+
340+ // Override the configuration to test SkipHandler behavior
341+ Builder . Services . Configure < McpAuthenticationOptions > (
342+ McpAuthenticationDefaults . AuthenticationScheme ,
343+ options =>
344+ {
345+ options . ResourceMetadata = null ;
346+ options . Events . OnResourceMetadataRequest = async context =>
347+ {
348+ // Call SkipHandler() to discontinue processing in the current handler
349+ context . SkipHandler ( ) ;
350+ await Task . CompletedTask ;
351+ } ;
352+ }
353+ ) ;
354+
355+ await using var app = Builder . Build ( ) ;
356+
357+ app . MapMcp ( ) . RequireAuthorization ( ) ;
358+
359+ await app . StartAsync ( TestContext . Current . CancellationToken ) ;
360+
361+ // Make a direct request to the resource metadata endpoint
362+ using var response = await HttpClient . GetAsync (
363+ "/.well-known/oauth-protected-resource" ,
364+ TestContext . Current . CancellationToken
365+ ) ;
366+
367+ // When SkipHandler() is called, the authentication handler should skip processing
368+ // and let other handlers in the pipeline handle the request. Since there are no
369+ // other handlers configured for this endpoint, this should result in a 404
370+ Assert . Equal ( HttpStatusCode . NotFound , response . StatusCode ) ;
371+ }
372+
292373 private async Task < string ? > HandleAuthorizationUrlAsync (
293374 Uri authorizationUri ,
294375 Uri redirectUri ,
0 commit comments