|
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