From 4985a913b7e675a12f973ed479337cd669138518 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 11 Jan 2023 15:39:23 -0700 Subject: [PATCH 1/6] - add failing test --- tests/wpunit/QueryAnalyzerTest.php | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/tests/wpunit/QueryAnalyzerTest.php b/tests/wpunit/QueryAnalyzerTest.php index 3cf8d1376..da5ceb547 100644 --- a/tests/wpunit/QueryAnalyzerTest.php +++ b/tests/wpunit/QueryAnalyzerTest.php @@ -11,6 +11,8 @@ public function _setUp():void { 'post_title' => 'test post' ]); + WPGraphQL::clear_schema(); + } public function _tearDown():void { @@ -79,4 +81,78 @@ public function testQueryTypes() { $this->assertEqualSets( [ 'rootquery', 'rootquerytopostconnection', 'post' ], $types ); } + public function testQueryForListOfNonNodeInterfaceTypesDoesntAddKeys() { + + // types that do not implement the "Node" interface shouldn't be tracked as keys + // in the Query Analyzer + + add_action( 'graphql_register_types', function() { + register_graphql_interface_type( 'TestInterface', [ + 'eagerlyLoadType' => true, + 'fields' => [ + 'test' => [ + 'type' => 'String', + ], + ], + 'resolveType' => function () { + return 'TestType'; + }, + ] ); + + register_graphql_object_type( 'TestType', [ + 'eagerlyLoadType' => true, + 'interfaces' => [ 'TestInterface' ], + 'fields' => [ + 'test' => [ + 'type' => 'String', + ], + ], + ] ); + + register_graphql_field( 'Post', 'testField', [ + 'type' => [ 'list_of' => 'TestInterface' ], + 'resolve' => function () { + return [ + [ + 'test' => 'value', + ], + [ + 'test' => 'value', + ], + ]; + }, + ] ); + } ); + + + $query = ' + { + posts { + nodes { + testField { + test + } + } + } + } + '; + + $request = graphql([ + 'query' => $query + ], true ); + + $request->execute(); + + $list_types = $request->get_query_analyzer()->get_list_types(); + + codecept_debug( $list_types ); + $keys_array = $list_types; + codecept_debug( $list_types ); + + $this->assertNotContains( 'list:testinterface', $list_types ); + $this->assertNotContains( 'list:testtype', $list_types ); + $this->assertContains( 'list:post', $list_types ); + + } + } From 1984d007abee3fd811ad5e99a9dc6cfaf8eab84b Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 11 Jan 2023 15:48:06 -0700 Subject: [PATCH 2/6] - adjust how the list types are generated to not add non-node types when resolved from an interface --- src/Utils/QueryAnalyzer.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Utils/QueryAnalyzer.php b/src/Utils/QueryAnalyzer.php index 0e876e046..ca46c7996 100644 --- a/src/Utils/QueryAnalyzer.php +++ b/src/Utils/QueryAnalyzer.php @@ -352,13 +352,16 @@ public function set_list_types( ?Schema $schema, ?string $query ): array { // with a double __, then it should be tracked if ( $is_list_type && 0 !== strpos( $named_type, '__' ) ) { - // if the Type is not a Node, and has a "node" field, - // lets get the named type of the node, not the edge - if ( in_array( 'node', $named_type->getFieldNames(), true ) && ! in_array( 'Node', array_keys( $named_type->getInterfaces() ), true ) ) { + // if the type doesn't apply the node interface + if ( array_key_exists( 'Node', $named_type->getInterfaces() ) ) { + // if the Type is not a Node, and has a "node" field, + // lets get the named type of the node, not the edge + $type_map[] = 'list:' . strtolower( $named_type ); + } else if ( in_array( 'node', $named_type->getFieldNames(), true ) ) { $named_type = $named_type->getField( 'node' )->getType(); + $type_map[] = 'list:' . strtolower( $named_type ); } - $type_map[] = 'list:' . strtolower( $named_type ); } } @@ -369,7 +372,15 @@ public function set_list_types( ?Schema $schema, ?string $query ): array { foreach ( $possible_types as $possible_type ) { // if the type is a list, store it if ( $is_list_type && 0 !== strpos( $possible_type, '__' ) ) { - $type_map[] = 'list:' . strtolower( $possible_type ); + // if the type doesn't apply the node interface + if ( array_key_exists( 'Node', $named_type->getInterfaces() ) ) { + // if the Type is not a Node, and has a "node" field, + // lets get the named type of the node, not the edge + $type_map[] = 'list:' . strtolower( $named_type ); + } else if ( in_array( 'node', $named_type->getFieldNames(), true ) ) { + $named_type = $named_type->getField( 'node' )->getType(); + $type_map[] = 'list:' . strtolower( $named_type ); + } } } } From 2ae4662ec8eb0bafd25e4d1be22b73a3158ee652 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 11 Jan 2023 16:03:57 -0700 Subject: [PATCH 3/6] - adjust how the list types are generated to not add non-node types when resolved from an interface --- src/Utils/QueryAnalyzer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Utils/QueryAnalyzer.php b/src/Utils/QueryAnalyzer.php index ca46c7996..9943928c1 100644 --- a/src/Utils/QueryAnalyzer.php +++ b/src/Utils/QueryAnalyzer.php @@ -373,13 +373,13 @@ public function set_list_types( ?Schema $schema, ?string $query ): array { // if the type is a list, store it if ( $is_list_type && 0 !== strpos( $possible_type, '__' ) ) { // if the type doesn't apply the node interface - if ( array_key_exists( 'Node', $named_type->getInterfaces() ) ) { + if ( array_key_exists( 'Node', $possible_type->getInterfaces() ) ) { // if the Type is not a Node, and has a "node" field, // lets get the named type of the node, not the edge - $type_map[] = 'list:' . strtolower( $named_type ); - } else if ( in_array( 'node', $named_type->getFieldNames(), true ) ) { + $type_map[] = 'list:' . strtolower( $possible_type ); + } else if ( in_array( 'node', $possible_type->getFieldNames(), true ) ) { $named_type = $named_type->getField( 'node' )->getType(); - $type_map[] = 'list:' . strtolower( $named_type ); + $type_map[] = 'list:' . strtolower( $possible_type ); } } } From bf3b5753fadfd48e49b636c6f36e1c37a014501d Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 11 Jan 2023 16:10:59 -0700 Subject: [PATCH 4/6] - code formatting adjustments --- src/Utils/QueryAnalyzer.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Utils/QueryAnalyzer.php b/src/Utils/QueryAnalyzer.php index 9943928c1..53acd48ee 100644 --- a/src/Utils/QueryAnalyzer.php +++ b/src/Utils/QueryAnalyzer.php @@ -357,11 +357,10 @@ public function set_list_types( ?Schema $schema, ?string $query ): array { // if the Type is not a Node, and has a "node" field, // lets get the named type of the node, not the edge $type_map[] = 'list:' . strtolower( $named_type ); - } else if ( in_array( 'node', $named_type->getFieldNames(), true ) ) { + } elseif ( in_array( 'node', $named_type->getFieldNames(), true ) ) { $named_type = $named_type->getField( 'node' )->getType(); $type_map[] = 'list:' . strtolower( $named_type ); - } - + } } } @@ -377,7 +376,7 @@ public function set_list_types( ?Schema $schema, ?string $query ): array { // if the Type is not a Node, and has a "node" field, // lets get the named type of the node, not the edge $type_map[] = 'list:' . strtolower( $possible_type ); - } else if ( in_array( 'node', $possible_type->getFieldNames(), true ) ) { + } elseif ( in_array( 'node', $possible_type->getFieldNames(), true ) ) { $named_type = $named_type->getField( 'node' )->getType(); $type_map[] = 'list:' . strtolower( $possible_type ); } From 240171511066d9965ebc4d1a791257ee098f7a0e Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 11 Jan 2023 16:23:32 -0700 Subject: [PATCH 5/6] - ensure there are interfaces before checking their keys --- src/Utils/QueryAnalyzer.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Utils/QueryAnalyzer.php b/src/Utils/QueryAnalyzer.php index 53acd48ee..8ae289f57 100644 --- a/src/Utils/QueryAnalyzer.php +++ b/src/Utils/QueryAnalyzer.php @@ -351,16 +351,15 @@ public function set_list_types( ?Schema $schema, ?string $query ): array { // if the type is a list and the named type doesn't start // with a double __, then it should be tracked if ( $is_list_type && 0 !== strpos( $named_type, '__' ) ) { - // if the type doesn't apply the node interface - if ( array_key_exists( 'Node', $named_type->getInterfaces() ) ) { + if ( ! empty( $named_type->getInterfaces() ) && array_key_exists( 'Node', $named_type->getInterfaces() ) ) { // if the Type is not a Node, and has a "node" field, // lets get the named type of the node, not the edge $type_map[] = 'list:' . strtolower( $named_type ); } elseif ( in_array( 'node', $named_type->getFieldNames(), true ) ) { $named_type = $named_type->getField( 'node' )->getType(); $type_map[] = 'list:' . strtolower( $named_type ); - } + } } } @@ -372,7 +371,7 @@ public function set_list_types( ?Schema $schema, ?string $query ): array { // if the type is a list, store it if ( $is_list_type && 0 !== strpos( $possible_type, '__' ) ) { // if the type doesn't apply the node interface - if ( array_key_exists( 'Node', $possible_type->getInterfaces() ) ) { + if ( ! empty( $possible_type->getInterfaces() ) && array_key_exists( 'Node', $possible_type->getInterfaces() ) ) { // if the Type is not a Node, and has a "node" field, // lets get the named type of the node, not the edge $type_map[] = 'list:' . strtolower( $possible_type ); From 12fb5b296d0f54b700337cd492793bcd4468785a Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 11 Jan 2023 16:33:30 -0700 Subject: [PATCH 6/6] - code formatting adjustments --- src/Utils/QueryAnalyzer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/QueryAnalyzer.php b/src/Utils/QueryAnalyzer.php index 8ae289f57..7238ac1ed 100644 --- a/src/Utils/QueryAnalyzer.php +++ b/src/Utils/QueryAnalyzer.php @@ -371,7 +371,7 @@ public function set_list_types( ?Schema $schema, ?string $query ): array { // if the type is a list, store it if ( $is_list_type && 0 !== strpos( $possible_type, '__' ) ) { // if the type doesn't apply the node interface - if ( ! empty( $possible_type->getInterfaces() ) && array_key_exists( 'Node', $possible_type->getInterfaces() ) ) { + if ( ! empty( $possible_type->getInterfaces() ) && array_key_exists( 'Node', $possible_type->getInterfaces() ) ) { // if the Type is not a Node, and has a "node" field, // lets get the named type of the node, not the edge $type_map[] = 'list:' . strtolower( $possible_type );