|
1 | 1 | from base64 import b64encode |
| 2 | +from typing import Any |
| 3 | +from typing import cast |
2 | 4 |
|
3 | 5 | import pytest |
4 | 6 | from jsonschema import ValidationError |
| 7 | +from jsonschema.exceptions import ( |
| 8 | + _WrappedReferencingError as WrappedReferencingError, |
| 9 | +) |
5 | 10 | from referencing import Registry |
6 | 11 | from referencing import Resource |
| 12 | +from referencing.exceptions import InvalidAnchor |
| 13 | +from referencing.exceptions import NoSuchAnchor |
| 14 | +from referencing.exceptions import PointerToNowhere |
7 | 15 | from referencing.jsonschema import DRAFT202012 |
8 | 16 |
|
9 | 17 | from openapi_schema_validator import OAS30ReadValidator |
@@ -353,6 +361,96 @@ def test_oneof_required(self, validator_class): |
353 | 361 | result = validator.validate(instance) |
354 | 362 | assert result is None |
355 | 363 |
|
| 364 | + @pytest.mark.parametrize( |
| 365 | + "mapping_ref", |
| 366 | + [ |
| 367 | + "#/components/schemas/Missing", |
| 368 | + "#missing-anchor", |
| 369 | + "#bad/frag", |
| 370 | + ], |
| 371 | + ) |
| 372 | + def test_discriminator_handles_unresolvable_reference_kinds( |
| 373 | + self, mapping_ref |
| 374 | + ): |
| 375 | + schema = { |
| 376 | + "oneOf": [{"$ref": "#/components/schemas/MountainHiking"}], |
| 377 | + "discriminator": { |
| 378 | + "propertyName": "discipline", |
| 379 | + "mapping": {"mountain_hiking": mapping_ref}, |
| 380 | + }, |
| 381 | + "components": { |
| 382 | + "schemas": { |
| 383 | + "MountainHiking": { |
| 384 | + "type": "object", |
| 385 | + "properties": { |
| 386 | + "discipline": {"type": "string"}, |
| 387 | + "length": {"type": "integer"}, |
| 388 | + }, |
| 389 | + "required": ["discipline", "length"], |
| 390 | + }, |
| 391 | + }, |
| 392 | + }, |
| 393 | + } |
| 394 | + |
| 395 | + validator = OAS30Validator( |
| 396 | + schema, |
| 397 | + format_checker=oas30_format_checker, |
| 398 | + ) |
| 399 | + with pytest.raises( |
| 400 | + ValidationError, |
| 401 | + match=f"reference '{mapping_ref}' could not be resolved", |
| 402 | + ): |
| 403 | + validator.validate( |
| 404 | + { |
| 405 | + "discipline": "mountain_hiking", |
| 406 | + "length": 10, |
| 407 | + } |
| 408 | + ) |
| 409 | + |
| 410 | + @pytest.mark.parametrize( |
| 411 | + "mapping_ref, expected_cause", |
| 412 | + [ |
| 413 | + ("#/components/schemas/Missing", PointerToNowhere), |
| 414 | + ("#missing-anchor", NoSuchAnchor), |
| 415 | + ("#bad/frag", InvalidAnchor), |
| 416 | + ], |
| 417 | + ) |
| 418 | + def test_discriminator_unresolvable_reference_causes( |
| 419 | + self, mapping_ref, expected_cause |
| 420 | + ): |
| 421 | + schema = { |
| 422 | + "oneOf": [{"$ref": "#/components/schemas/MountainHiking"}], |
| 423 | + "discriminator": { |
| 424 | + "propertyName": "discipline", |
| 425 | + "mapping": {"mountain_hiking": mapping_ref}, |
| 426 | + }, |
| 427 | + "components": { |
| 428 | + "schemas": { |
| 429 | + "MountainHiking": { |
| 430 | + "type": "object", |
| 431 | + "properties": { |
| 432 | + "discipline": {"type": "string"}, |
| 433 | + "length": {"type": "integer"}, |
| 434 | + }, |
| 435 | + "required": ["discipline", "length"], |
| 436 | + }, |
| 437 | + }, |
| 438 | + }, |
| 439 | + } |
| 440 | + |
| 441 | + validator = OAS30Validator( |
| 442 | + schema, |
| 443 | + format_checker=oas30_format_checker, |
| 444 | + ) |
| 445 | + |
| 446 | + with pytest.raises(WrappedReferencingError) as exc_info: |
| 447 | + cast(Any, validator)._validate_reference( |
| 448 | + ref=mapping_ref, |
| 449 | + instance={"discipline": "mountain_hiking", "length": 10}, |
| 450 | + ) |
| 451 | + |
| 452 | + assert isinstance(exc_info.value.__cause__, expected_cause) |
| 453 | + |
356 | 454 | @pytest.mark.parametrize( |
357 | 455 | "schema_type", |
358 | 456 | [ |
|
0 commit comments