Skip to content

Commit 4eac10f

Browse files
committed
fix(oas3.1): correctly validate paths using $ref
Schemathesis uses static version of the current published version of the OpenApi 3.1 spec metaschema (https://spec.openapis.org/oas/3.1/schema/2022-10-07) to validate openapi 3.1 spec documents. Unfortunately, the published version has at least one known bug in which the schema for `paths` references the definition of a concrete `path-item` instead of `path-item-or-reference`, which might still be technically incorrect when it comes handling the case of ref and sibling fields, but is correct according to the documented definition of a pathItemObject. This oversight has been noticed multiple times OAI/OpenAPI-Specification#3298 OAI/OpenAPI-Specification#2635 (comment) OAI/OpenAPI-Specification#2635 (comment) OAI/OpenAPI-Specification#3513 OAI/OpenAPI-Specification#2657 (comment) And finally fixed in Feb 2024 OAI/OpenAPI-Specification#3355 with a slightly bigger rework of the pathItem schema. Sadly, due to confusion about how to release fixes in schemas OAI/OpenAPI-Specification#151 (comment) this change has not been published anywhere except schema.yaml in the git repo, not even in schema.json, which appearantly only gets refreshed once per release of the metaschema OAI/OpenAPI-Specification#3355 (comment) This commit updates the stored schema from the most up-to-date 3.1.0 schema.yaml from 0035208 to close the bug and make spec-valid openapi spec files that use $ref under path finally validate correctly in schemathesis. It also adds a corresponding regression test
1 parent 51289c0 commit 4eac10f

File tree

3 files changed

+26
-11
lines changed

3 files changed

+26
-11
lines changed

docs/changelog.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ Changelog
66

77
.. _v3.36.2:
88

9+
**Fixed**
10+
- OpenApi3.1 spec using $ref in a path is incorrectly validated as invalid
11+
912
:version:`3.36.2 <v3.36.1...v3.36.2>` - 2024-09-26
1013
--------------------------------------------------
1114

src/schemathesis/specs/openapi/definitions.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,8 @@
13301330
},
13311331
},
13321332
}
1333+
# Generated from the updated schema.yaml from 0035208, which includes unpublished bugfixes
1334+
# https://github.com/OAI/OpenAPI-Specification/blob/0035208611701b4f7f2c959eb99a8725cca41e6e/schemas/v3.1/schema.yaml
13331335
OPENAPI_31 = {
13341336
"$id": "https://spec.openapis.org/oas/3.1/schema/2022-10-07",
13351337
"$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -1345,7 +1347,7 @@
13451347
},
13461348
"servers": {"type": "array", "items": {"$ref": "#/$defs/server"}, "default": [{"url": "/"}]},
13471349
"paths": {"$ref": "#/$defs/paths"},
1348-
"webhooks": {"type": "object", "additionalProperties": {"$ref": "#/$defs/path-item-or-reference"}},
1350+
"webhooks": {"type": "object", "additionalProperties": {"$ref": "#/$defs/path-item"}},
13491351
"components": {"$ref": "#/$defs/components"},
13501352
"security": {"type": "array", "items": {"$ref": "#/$defs/security-requirement"}},
13511353
"tags": {"type": "array", "items": {"$ref": "#/$defs/tag"}},
@@ -1400,7 +1402,7 @@
14001402
"$comment": "https://spec.openapis.org/oas/v3.1.0#server-object",
14011403
"type": "object",
14021404
"properties": {
1403-
"url": {"type": "string", "format": "uri-reference"},
1405+
"url": {"type": "string"},
14041406
"description": {"type": "string"},
14051407
"variables": {"type": "object", "additionalProperties": {"$ref": "#/$defs/server-variable"}},
14061408
},
@@ -1439,7 +1441,7 @@
14391441
},
14401442
"links": {"type": "object", "additionalProperties": {"$ref": "#/$defs/link-or-reference"}},
14411443
"callbacks": {"type": "object", "additionalProperties": {"$ref": "#/$defs/callbacks-or-reference"}},
1442-
"pathItems": {"type": "object", "additionalProperties": {"$ref": "#/$defs/path-item-or-reference"}},
1444+
"pathItems": {"type": "object", "additionalProperties": {"$ref": "#/$defs/path-item"}},
14431445
},
14441446
"patternProperties": {
14451447
"^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$": {
@@ -1461,6 +1463,7 @@
14611463
"$comment": "https://spec.openapis.org/oas/v3.1.0#path-item-object",
14621464
"type": "object",
14631465
"properties": {
1466+
"$ref": {"type": "string", "format": "uri-reference"},
14641467
"summary": {"type": "string"},
14651468
"description": {"type": "string"},
14661469
"servers": {"type": "array", "items": {"$ref": "#/$defs/server"}},
@@ -1477,11 +1480,6 @@
14771480
"$ref": "#/$defs/specification-extensions",
14781481
"unevaluatedProperties": False,
14791482
},
1480-
"path-item-or-reference": {
1481-
"if": {"type": "object", "required": ["$ref"]},
1482-
"then": {"$ref": "#/$defs/reference"},
1483-
"else": {"$ref": "#/$defs/path-item"},
1484-
},
14851483
"operation": {
14861484
"$comment": "https://spec.openapis.org/oas/v3.1.0#operation-object",
14871485
"type": "object",
@@ -1542,7 +1540,6 @@
15421540
"if": {"properties": {"in": {"const": "path"}}, "required": ["in"]},
15431541
"then": {
15441542
"properties": {
1545-
"name": {"pattern": "[^/#?]+$"},
15461543
"style": {"default": "simple", "enum": ["matrix", "label", "simple"]},
15471544
"required": {"const": True},
15481545
},
@@ -1662,7 +1659,7 @@
16621659
"$comment": "https://spec.openapis.org/oas/v3.1.0#callback-object",
16631660
"type": "object",
16641661
"$ref": "#/$defs/specification-extensions",
1665-
"additionalProperties": {"$ref": "#/$defs/path-item-or-reference"},
1662+
"additionalProperties": {"$ref": "#/$defs/path-item"},
16661663
},
16671664
"callbacks-or-reference": {
16681665
"if": {"type": "object", "required": ["$ref"]},
@@ -1755,7 +1752,6 @@
17551752
"summary": {"type": "string"},
17561753
"description": {"type": "string"},
17571754
},
1758-
"unevaluatedProperties": False,
17591755
},
17601756
"schema": {
17611757
"$comment": "https://spec.openapis.org/oas/v3.1.0#schema-object",

test/experimental/test_openapi_3_1.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,19 @@ def test_openapi_3_1_schema_validation():
8383
}
8484
with pytest.raises(SchemaError):
8585
from_dict(raw_schema, validate_schema=True, force_schema_version="30")
86+
87+
88+
def test_openapi_3_1_regression_path_ref():
89+
OPEN_API_3_1.enable()
90+
raw_schema = {
91+
"openapi": "3.1.0",
92+
"info": {"title": "Test correct validation of spec using $ref in pathItem", "version": "0.0.1"},
93+
"paths": {
94+
"/foo": {
95+
"get": {"summary": "dummy", "operationId": "dummy", "responses": {"200": {"description": "Success"}}}
96+
},
97+
"/bar": {"$ref": "#/paths/~1bar"},
98+
},
99+
}
100+
101+
from_dict(raw_schema,validate_schema=True)

0 commit comments

Comments
 (0)