@@ -363,6 +363,110 @@ def test_request_validation_disabled_response_validation_enabled(self) -> None:
363
363
self .assertEqual (start_response .status , "500 Internal Server Error" )
364
364
365
365
366
+ class TestServerRequestValidation (RequestValidationBase ): # noqa: D101
367
+
368
+ openapi_spec = (
369
+ b"openapi: '3.1.0'\n "
370
+ b"info:\n "
371
+ b" version: '1.0.0'\n "
372
+ b" title: Foo API\n "
373
+ b"servers:\n "
374
+ b" - url: /prefix/v1\n "
375
+ b" - url: http://example.com/prefix\n "
376
+ b"paths:\n "
377
+ b" /foo:\n "
378
+ b" get:\n "
379
+ b" responses:\n "
380
+ b" 200:\n "
381
+ b" description: A foo\n "
382
+ b" content:\n "
383
+ b" application/json:\n "
384
+ b" schema:\n "
385
+ b" type: object\n "
386
+ b" properties:\n "
387
+ b" test:\n "
388
+ b" type: string\n "
389
+ b" 400:\n "
390
+ b" description: Bad Request\n "
391
+ )
392
+
393
+ def test_server_validation_works_with_script_name (self ) -> None :
394
+ """Expect to find a match for http://localhost:8080/prefix/v1/foo."""
395
+ self ._add_view (lambda * arg : {"test" : "correct" })
396
+ # run request through router
397
+ router = Router (self .config .registry )
398
+ environ = {
399
+ "wsgi.url_scheme" : "http" ,
400
+ "SERVER_NAME" : "localhost" ,
401
+ "SERVER_PORT" : "8080" ,
402
+ "REQUEST_METHOD" : "GET" ,
403
+ "SCRIPT_NAME" : "/prefix/v1" ,
404
+ "PATH_INFO" : "/foo" ,
405
+ "HTTP_ACCEPT" : "application/json" ,
406
+ }
407
+ start_response = DummyStartResponse ()
408
+ response = router (environ , start_response )
409
+
410
+ self .assertEqual (start_response .status , "200 OK" )
411
+ self .assertEqual (json .loads (response [0 ]), {"test" : "correct" })
412
+
413
+ def test_server_validation_works_with_script_name_and_hostname (self ) -> None :
414
+ """Expect to find a match for http://example.com/prefix/foo."""
415
+ self ._add_view (lambda * arg : {"test" : "correct" })
416
+ # run request through router
417
+ router = Router (self .config .registry )
418
+ environ = {
419
+ "wsgi.url_scheme" : "http" ,
420
+ "SERVER_NAME" : "localhost" ,
421
+ "SERVER_PORT" : "8080" ,
422
+ "REQUEST_METHOD" : "GET" ,
423
+ "SCRIPT_NAME" : "/prefix" ,
424
+ "PATH_INFO" : "/foo" ,
425
+ "HTTP_HOST" : "example.com" ,
426
+ "HTTP_ACCEPT" : "application/json" ,
427
+ }
428
+ start_response = DummyStartResponse ()
429
+ response = router (environ , start_response )
430
+
431
+ self .assertEqual (start_response .status , "200 OK" )
432
+ self .assertEqual (json .loads (response [0 ]), {"test" : "correct" })
433
+
434
+ def test_server_validation_fails_with_bad_hostname (self ) -> None :
435
+ """Expect to fail for /prefix/v2/foo."""
436
+ self ._add_view ()
437
+ # run request through router
438
+ router = Router (self .config .registry )
439
+ environ = {
440
+ "wsgi.url_scheme" : "http" ,
441
+ "SERVER_NAME" : "localhost" ,
442
+ "SERVER_PORT" : "8080" ,
443
+ "REQUEST_METHOD" : "GET" ,
444
+ "SCRIPT_NAME" : "/prefix/v2" ,
445
+ "PATH_INFO" : "/foo" ,
446
+ "HTTP_HOST" : "example.com" ,
447
+ "HTTP_ACCEPT" : "application/json" ,
448
+ }
449
+ start_response = DummyStartResponse ()
450
+ with self .assertLogs (level = "ERROR" ) as cm :
451
+ response = router (environ , start_response )
452
+ self .assertEqual (start_response .status , "500 Internal Server Error" )
453
+ self .assertEqual (
454
+ json .loads (response [0 ]),
455
+ [
456
+ {
457
+ "exception" : "ServerNotFound" ,
458
+ "message" : "Server not found for http://example.com/prefix/v2/foo" ,
459
+ }
460
+ ],
461
+ )
462
+ self .assertEqual (
463
+ cm .output ,
464
+ [
465
+ "ERROR:pyramid_openapi3:Server not found for http://example.com/prefix/v2/foo"
466
+ ],
467
+ )
468
+
469
+
366
470
class TestImproperAPISpecValidation (RequestValidationBase ): # noqa: D101
367
471
368
472
openapi_spec = (
0 commit comments