|
14 | 14 | GraphQLObjectType,
|
15 | 15 | GraphQLSchema,
|
16 | 16 | GraphQLString,
|
| 17 | + is_enum_type, |
17 | 18 | )
|
18 | 19 | from graphql.utilities import (
|
19 | 20 | build_schema,
|
@@ -315,7 +316,7 @@ def builds_a_schema_with_an_enum():
|
315 | 316 | client_food_enum = client_schema.get_type("Food")
|
316 | 317 |
|
317 | 318 | # It's also an Enum type on the client.
|
318 |
| - assert isinstance(client_food_enum, GraphQLEnumType) |
| 319 | + assert is_enum_type(client_food_enum) |
319 | 320 |
|
320 | 321 | values = client_food_enum.values
|
321 | 322 | descriptions = {name: value.description for name, value in values.items()}
|
@@ -452,84 +453,81 @@ class Data:
|
452 | 453 |
|
453 | 454 |
|
454 | 455 | def describe_throws_when_given_incomplete_introspection():
|
455 |
| - def throws_when_given_empty_types(): |
456 |
| - incomplete_introspection = { |
457 |
| - "__schema": {"queryType": {"name": "QueryType"}, "types": []} |
| 456 | + dummy_schema = build_schema( |
| 457 | + """ |
| 458 | + type Query { |
| 459 | + foo: String |
458 | 460 | }
|
459 | 461 |
|
| 462 | + directive @Foo on QUERY |
| 463 | + """ |
| 464 | + ) |
| 465 | + |
| 466 | + def throws_when_given_empty_types(): |
| 467 | + introspection = introspection_from_schema(dummy_schema) |
| 468 | + |
| 469 | + introspection["__schema"]["types"] = [] |
| 470 | + |
460 | 471 | with raises(TypeError) as exc_info:
|
461 |
| - build_client_schema(incomplete_introspection) |
| 472 | + build_client_schema(introspection) |
462 | 473 |
|
463 | 474 | assert str(exc_info.value) == (
|
464 |
| - "Invalid or incomplete schema, unknown type: QueryType." |
| 475 | + "Invalid or incomplete schema, unknown type: Query." |
465 | 476 | " Ensure that a full introspection query is used"
|
466 | 477 | " in order to build a client schema."
|
467 | 478 | )
|
468 | 479 |
|
469 | 480 | def throws_when_missing_kind():
|
470 |
| - incomplete_introspection = { |
471 |
| - "__schema": { |
472 |
| - "queryType": {"name": "QueryType"}, |
473 |
| - "types": [{"name": "QueryType"}], |
474 |
| - } |
475 |
| - } |
| 481 | + introspection = introspection_from_schema(dummy_schema) |
| 482 | + |
| 483 | + query_type_introspection = introspection["__schema"]["types"][0] |
| 484 | + assert query_type_introspection["name"] == "Query" |
| 485 | + assert query_type_introspection["kind"] == "OBJECT" |
| 486 | + del query_type_introspection["kind"] |
476 | 487 |
|
477 | 488 | with raises(TypeError) as exc_info:
|
478 |
| - build_client_schema(incomplete_introspection) |
| 489 | + build_client_schema(introspection) |
479 | 490 |
|
480 |
| - assert str(exc_info.value) == ( |
| 491 | + assert str(exc_info.value).startswith( |
481 | 492 | "Invalid or incomplete introspection result."
|
482 | 493 | " Ensure that a full introspection query is used"
|
483 |
| - " in order to build a client schema: {'name': 'QueryType'}" |
| 494 | + " in order to build a client schema: {'name': 'Query'" |
484 | 495 | )
|
485 | 496 |
|
486 | 497 | def throws_when_missing_interfaces():
|
487 |
| - null_interface_introspection = { |
488 |
| - "__schema": { |
489 |
| - "queryType": {"name": "QueryType"}, |
490 |
| - "types": [ |
491 |
| - { |
492 |
| - "kind": "OBJECT", |
493 |
| - "name": "QueryType", |
494 |
| - "fields": [ |
495 |
| - { |
496 |
| - "name": "aString", |
497 |
| - "args": [], |
498 |
| - "type": { |
499 |
| - "kind": "SCALAR", |
500 |
| - "name": "String", |
501 |
| - "ofType": None, |
502 |
| - }, |
503 |
| - "isDeprecated": False, |
504 |
| - } |
505 |
| - ], |
506 |
| - } |
507 |
| - ], |
508 |
| - } |
509 |
| - } |
| 498 | + introspection = introspection_from_schema(dummy_schema) |
| 499 | + |
| 500 | + query_type_introspection = introspection["__schema"]["types"][0] |
| 501 | + assert query_type_introspection["name"] == "Query" |
| 502 | + assert query_type_introspection["interfaces"] == [] |
| 503 | + del query_type_introspection["interfaces"] |
510 | 504 |
|
511 | 505 | with raises(TypeError) as exc_info:
|
512 |
| - build_client_schema(null_interface_introspection) |
| 506 | + build_client_schema(introspection) |
513 | 507 |
|
514 | 508 | assert str(exc_info.value) == (
|
515 | 509 | "Introspection result missing interfaces:"
|
516 |
| - " {'kind': 'OBJECT', 'name': 'QueryType'," |
517 |
| - " 'fields': [{'name': 'aString', 'args': []," |
| 510 | + " {'kind': 'OBJECT', 'name': 'Query', 'description': None," |
| 511 | + " 'fields': [{'name': 'foo', 'description': None, 'args': []," |
518 | 512 | " 'type': {'kind': 'SCALAR', 'name': 'String', 'ofType': None},"
|
519 |
| - " 'isDeprecated': False}]}" |
| 513 | + " 'isDeprecated': False, 'deprecationReason': None}]," |
| 514 | + " 'inputFields': None, 'enumValues': None, 'possibleTypes': None}" |
520 | 515 | )
|
521 | 516 |
|
522 | 517 | def throws_when_missing_directive_locations():
|
523 |
| - introspection = { |
524 |
| - "__schema": {"types": [], "directives": [{"name": "test", "args": []}]} |
525 |
| - } |
| 518 | + introspection = introspection_from_schema(dummy_schema) |
| 519 | + |
| 520 | + foo_directive_introspection = introspection["__schema"]["directives"][0] |
| 521 | + assert foo_directive_introspection["name"] == "Foo" |
| 522 | + assert foo_directive_introspection["locations"] == ["QUERY"] |
| 523 | + del foo_directive_introspection["locations"] |
526 | 524 |
|
527 | 525 | with raises(TypeError) as exc_info:
|
528 | 526 | build_client_schema(introspection)
|
529 | 527 |
|
530 | 528 | assert str(exc_info.value) == (
|
531 | 529 | "Introspection result missing directive locations:"
|
532 |
| - " {'name': 'test', 'args': []}" |
| 530 | + " {'name': 'Foo', 'description': None, 'args': []}" |
533 | 531 | )
|
534 | 532 |
|
535 | 533 |
|
@@ -584,42 +582,58 @@ def succeeds_on_deep_types_less_or_equal_7_levels():
|
584 | 582 |
|
585 | 583 | assert cycle_introspection(sdl) == sdl
|
586 | 584 |
|
587 |
| - def describe_prevents_infinite_recursion_on_invalid_introspection(): |
588 |
| - def recursive_interfaces(): |
589 |
| - introspection = { |
590 |
| - "__schema": { |
591 |
| - "types": [ |
592 |
| - { |
593 |
| - "name": "Foo", |
594 |
| - "kind": "OBJECT", |
595 |
| - "fields": [], |
596 |
| - "interfaces": [{"name": "Foo"}], |
597 |
| - } |
598 |
| - ] |
599 |
| - } |
600 |
| - } |
601 |
| - with raises(TypeError) as exc_info: |
602 |
| - build_client_schema(introspection) |
603 |
| - assert str(exc_info.value) == ( |
604 |
| - "Foo interfaces cannot be resolved: " |
605 |
| - "Expected Foo to be a GraphQL Interface type." |
606 |
| - ) |
607 | 585 |
|
608 |
| - def recursive_union(): |
609 |
| - introspection = { |
610 |
| - "__schema": { |
611 |
| - "types": [ |
612 |
| - { |
613 |
| - "name": "Foo", |
614 |
| - "kind": "UNION", |
615 |
| - "possibleTypes": [{"name": "Foo"}], |
616 |
| - } |
617 |
| - ] |
618 |
| - } |
619 |
| - } |
620 |
| - with raises(TypeError) as exc_info: |
621 |
| - build_client_schema(introspection) |
622 |
| - assert str(exc_info.value) == ( |
623 |
| - "Foo types cannot be resolved: " |
624 |
| - "Expected Foo to be a GraphQL Object type." |
625 |
| - ) |
| 586 | +def describe_prevents_infinite_recursion_on_invalid_introspection(): |
| 587 | + def recursive_interfaces(): |
| 588 | + sdl = """ |
| 589 | + type Query { |
| 590 | + foo: Foo |
| 591 | + } |
| 592 | +
|
| 593 | + type Foo { |
| 594 | + foo: String |
| 595 | + } |
| 596 | + """ |
| 597 | + schema = build_schema(sdl, assume_valid=True) |
| 598 | + introspection = introspection_from_schema(schema) |
| 599 | + |
| 600 | + foo_type_introspection = introspection["__schema"]["types"][1] |
| 601 | + assert foo_type_introspection["name"] == "Foo" |
| 602 | + assert foo_type_introspection["interfaces"] == [] |
| 603 | + # we need to patch here since invalid interfaces cannot be built with Python |
| 604 | + foo_type_introspection["interfaces"] = [ |
| 605 | + {"kind": "OBJECT", "name": "Foo", "ofType": None} |
| 606 | + ] |
| 607 | + |
| 608 | + with raises(TypeError) as exc_info: |
| 609 | + build_client_schema(introspection) |
| 610 | + assert str(exc_info.value) == ( |
| 611 | + "Foo interfaces cannot be resolved: " |
| 612 | + "Expected Foo to be a GraphQL Interface type." |
| 613 | + ) |
| 614 | + |
| 615 | + def recursive_union(): |
| 616 | + sdl = """ |
| 617 | + type Query { |
| 618 | + foo: Foo |
| 619 | + } |
| 620 | +
|
| 621 | + union Foo |
| 622 | + """ |
| 623 | + schema = build_schema(sdl, assume_valid=True) |
| 624 | + introspection = introspection_from_schema(schema) |
| 625 | + |
| 626 | + foo_type_introspection = introspection["__schema"]["types"][1] |
| 627 | + assert foo_type_introspection["name"] == "Foo" |
| 628 | + assert foo_type_introspection["kind"] == "UNION" |
| 629 | + assert foo_type_introspection["possibleTypes"] == [] |
| 630 | + # we need to patch here since invalid unions cannot be built with Python |
| 631 | + foo_type_introspection["possibleTypes"] = [ |
| 632 | + {"kind": "UNION", "name": "Foo", "ofType": None} |
| 633 | + ] |
| 634 | + |
| 635 | + with raises(TypeError) as exc_info: |
| 636 | + build_client_schema(introspection) |
| 637 | + assert str(exc_info.value) == ( |
| 638 | + "Foo types cannot be resolved: Expected Foo to be a GraphQL Object type." |
| 639 | + ) |
0 commit comments