diff --git a/Dockerfile b/Dockerfile index c050492e9..0b16146ca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,7 @@ RUN curl -sS https://getcomposer.org/installer | php -- \ ENV PATH "$PATH:~/.composer/vendor/bin" # Set PHPUnit version. -ARG PHPUNIT_VERSION="<=8.1.*" +ARG PHPUNIT_VERSION="<=8.1" # Install wp-browser globally RUN composer global require --optimize-autoloader \ wp-cli/wp-cli-bundle \ diff --git a/includes/class-core-schema-filters.php b/includes/class-core-schema-filters.php index 3f672f74b..12fa849df 100644 --- a/includes/class-core-schema-filters.php +++ b/includes/class-core-schema-filters.php @@ -73,6 +73,14 @@ public static function add_filters() { 10, 3 ); + + add_filter( + 'graphql_dataloader_get_model', + array( '\WPGraphQL\WooCommerce\Data\Loader\WC_Customer_Loader', 'inject_user_loader_models' ), + 10, + 3 + ); + add_filter( 'graphql_post_object_connection_query_args', array( '\WPGraphQL\WooCommerce\Connection\Orders', 'post_object_connection_query_args' ), @@ -100,6 +108,13 @@ public static function add_filters() { 10, 7 ); + + add_filter( + 'graphql_map_input_fields_to_wp_user_query', + array( '\WPGraphQL\WooCommerce\Connection\Customers', 'map_input_fields_to_wp_query' ), + 10, + 6 + ); } /** diff --git a/includes/connection/class-customers.php b/includes/connection/class-customers.php index 01328cdec..6b8e6911c 100644 --- a/includes/connection/class-customers.php +++ b/includes/connection/class-customers.php @@ -11,6 +11,7 @@ use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; +use WPGraphQL\Data\Connection\UserConnectionResolver; use WPGraphQL\WooCommerce\Data\Factory; /** @@ -23,43 +24,62 @@ class Customers { */ public static function register_connections() { register_graphql_connection( - self::get_connection_config( - array( - 'fromType' => 'RootQuery', - 'toType' => 'Customer', - 'fromFieldName' => 'customers', - ) + array( + 'fromType' => 'RootQuery', + 'toType' => 'Customer', + 'fromFieldName' => 'customers', + 'connectionArgs' => self::get_connection_args(), + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $resolver = new UserConnectionResolver( $source, $args, $context, $info ); + + if ( ! self::should_execute() ) { + return array( + 'nodes' => array(), + 'edges' => array(), + ); + } + + $resolver->set_query_arg( 'role', 'customer' ); + + return $resolver->get_connection(); + }, ) ); register_graphql_connection( - self::get_connection_config( - array( - 'fromType' => 'Coupon', - 'toType' => 'Customer', - 'fromFieldName' => 'usedBy', - ) + array( + 'fromType' => 'Coupon', + 'toType' => 'Customer', + 'fromFieldName' => 'usedBy', + 'connectionArgs' => self::get_connection_args(), + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $resolver = new UserConnectionResolver( $source, $args, $context, $info ); + + $resolver->set_query_arg( 'include', $source->used_by_ids ); + $resolver->set_query_arg( 'role', 'customer' ); + + if ( ! self::should_execute() ) { + return array(); + } + + return $resolver->get_connection(); + }, ) ); } /** - * Given an array of $args, this returns the connection config, merging the provided args - * with the defaults + * Confirms the uses has the privileges to query Customer * - * @param array $args - Connection configuration. - * @return array + * @return bool */ - public static function get_connection_config( $args ): array { - return array_merge( - array( - 'connectionArgs' => self::get_connection_args(), - 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { - return Factory::resolve_customer_connection( $source, $args, $context, $info ); - }, - ), - $args - ); + public static function should_execute() { + switch ( true ) { + case current_user_can( 'list_users' ): + return true; + default: + return false; + } } /** @@ -69,42 +89,101 @@ public static function get_connection_config( $args ): array { */ public static function get_connection_args(): array { return array( - 'search' => array( + 'search' => array( 'type' => 'String', 'description' => __( 'Limit results to those matching a string.', 'wp-graphql-woocommerce' ), ), - 'exclude' => array( + 'exclude' => array( 'type' => array( 'list_of' => 'Int' ), 'description' => __( 'Ensure result set excludes specific IDs.', 'wp-graphql-woocommerce' ), ), - 'include' => array( + 'include' => array( 'type' => array( 'list_of' => 'Int' ), 'description' => __( 'Limit result set to specific ids.', 'wp-graphql-woocommerce' ), ), - 'email' => array( + 'email' => array( 'type' => 'String', 'description' => __( 'Limit result set to resources with a specific email.', 'wp-graphql-woocommerce' ), ), - 'role' => array( - 'type' => 'UserRoleEnum', - 'description' => __( 'Limit result set to resources with a specific role.', 'wp-graphql-woocommerce' ), - ), - 'roleIn' => array( - 'type' => array( 'list_of' => 'UserRoleEnum' ), - 'description' => __( 'Limit result set to resources with a specific group of roles.', 'wp-graphql-woocommerce' ), - ), - 'roleNotIn' => array( - 'type' => array( 'list_of' => 'UserRoleEnum' ), - 'description' => __( 'Limit result set to resources not within a specific group of roles.', 'wp-graphql-woocommerce' ), - ), - 'orderby' => array( + 'orderby' => array( 'type' => 'CustomerConnectionOrderbyEnum', 'description' => __( 'Order results by a specific field.', 'wp-graphql-woocommerce' ), ), - 'order' => array( + 'order' => array( 'type' => 'OrderEnum', 'description' => __( 'Order of results.', 'wp-graphql-woocommerce' ), ), ); } + + /** + * This allows plugins/themes to hook in and alter what $args should be allowed to be passed + * from a GraphQL Query to the WP_Query + * + * @param array $query_args The mapped query arguments. + * @param array $where_args Query "where" args. + * @param mixed $source The query results for a query calling this. + * @param array $args All of the arguments for the query (not just the "where" args). + * @param AppContext $context The AppContext object. + * @param ResolveInfo $info The ResolveInfo object. + * + * @return array Query arguments. + */ + public static function map_input_fields_to_wp_query( $query_args, $where_args, $source, $args, $context, $info ) { + $key_mapping = array( + 'search' => 'search', + 'exclude' => 'exclude', + 'include' => 'include', + ); + + foreach ( $key_mapping as $key => $field ) { + if ( ! empty( $where_args[ $key ] ) ) { + $query_args[ $field ] = $where_args[ $key ]; + } + } + + // Filter by email. + if ( ! empty( $where_args['email'] ) ) { + $query_args['search'] = $where_args['email']; + $query_args['search_columns'] = array( 'user_email' ); + } + + /** + * Map the orderby inputArgs to the WP_Query + */ + if ( ! empty( $where_args['orderby'] ) ) { + $query_args['orderby'] = $where_args['orderby']; + } + + /** + * Map the orderby inputArgs to the WP_Query + */ + if ( ! empty( $where_args['order'] ) ) { + $query_args['order'] = $where_args['order']; + } + + /** + * Filter the input fields + * This allows plugins/themes to hook in and alter what $args should be allowed to be passed + * from a GraphQL Query to the WP_Query + * + * @param array $args The mapped query arguments + * @param array $where_args Query "where" args + * @param mixed $source The query results for a query calling this + * @param array $all_args All of the arguments for the query (not just the "where" args) + * @param AppContext $context The AppContext object + * @param ResolveInfo $info The ResolveInfo object + */ + $query_args = apply_filters( + 'graphql_map_input_fields_to_customer_query', + $query_args, + $where_args, + $source, + $args, + $context, + $info + ); + + return $query_args; + } } diff --git a/includes/connection/class-products.php b/includes/connection/class-products.php index bce12ee46..bb06be6b5 100644 --- a/includes/connection/class-products.php +++ b/includes/connection/class-products.php @@ -11,7 +11,6 @@ use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; -use WPGraphQL\WooCommerce\Data\Connection\Product_Connection_Resolver; use WPGraphQL\Data\Connection\PostObjectConnectionResolver; /** diff --git a/includes/data/connection/class-cart-item-connection-resolver.php b/includes/data/connection/class-cart-item-connection-resolver.php index 71054028e..69053e3b9 100644 --- a/includes/data/connection/class-cart-item-connection-resolver.php +++ b/includes/data/connection/class-cart-item-connection-resolver.php @@ -21,10 +21,6 @@ * Class Cart_Item_Connection_Resolver */ class Cart_Item_Connection_Resolver extends AbstractConnectionResolver { - /** - * Include Db Loader connection common functions. - */ - use WC_Db_Loader_Common; /** * Return the name of the loader to be used with the connection resolver diff --git a/includes/data/connection/class-customer-connection-resolver.php b/includes/data/connection/class-customer-connection-resolver.php index 5e923809d..15d63a247 100644 --- a/includes/data/connection/class-customer-connection-resolver.php +++ b/includes/data/connection/class-customer-connection-resolver.php @@ -16,6 +16,8 @@ /** * Class Customer_Connection_Resolver + * + * @deprecated v0.10.0 */ class Customer_Connection_Resolver extends AbstractConnectionResolver { /** diff --git a/includes/data/connection/class-downloadable-item-connection-resolver.php b/includes/data/connection/class-downloadable-item-connection-resolver.php index f96079e32..aa05fc663 100644 --- a/includes/data/connection/class-downloadable-item-connection-resolver.php +++ b/includes/data/connection/class-downloadable-item-connection-resolver.php @@ -22,12 +22,6 @@ * Class Downloadable_Item_Connection_Resolver */ class Downloadable_Item_Connection_Resolver extends AbstractConnectionResolver { - /** - * Include Db Loader connection common functions. - */ - use WC_Db_Loader_Common; - - const PREFIX = 'DI'; /** * Return the name of the loader to be used with the connection resolver @@ -133,15 +127,27 @@ public function get_query() { } } - $cursor_key = $this->get_offset(); - $cursor_offset = array_search( $cursor_key, array_column( $items, 'download_id' ), true ) ?? null; + $cursor = $this->get_offset(); + $first = ! empty( $this->args['first'] ) ? $this->args['first'] : null; + $last = ! empty( $this->args['last'] ) ? $this->args['last'] : null; - if ( ! empty( $this->args['after'] ) ) { - $items = array_splice( $items, $cursor_offset + 1 ); - } elseif ( $cursor_offset ) { - $items = array_splice( $items, 0, $cursor_offset ); + // MUST DO FOR SANITY ~ If last, reverse list for correct slicing. + if ( $last ) { + $items = array_reverse( $items ); + } + + // Set offset. + $offset = $cursor + ? array_search( $cursor, array_column( $items, 'download_id' ), true ) + : 0; + + // If cursor set, move index up one to ensure cursor not included in keys. + if ( $cursor ) { + $offset++; } + $items = array_slice( $items, $offset, $this->query_amount + 1 ); + // Cache items for later. foreach ( $items as $item ) { $this->loader->prime( $item['download_id'], $item ); @@ -150,36 +156,6 @@ public function get_query() { return array_column( $items, 'download_id' ); } - /** - * This returns the offset to be used in the $query_args based on the $args passed to the - * GraphQL query. - * - * @return int|mixed - */ - public function get_offset() { - $offset = null; - - // Get the offset. - if ( ! empty( $this->args['after'] ) ) { - $offset = $this->cursor_to_offset( self::PREFIX, $this->args['after'] ); - } elseif ( ! empty( $this->args['before'] ) ) { - $offset = $this->cursor_to_offset( self::PREFIX, $this->args['before'] ); - } - - return $offset; - } - - /** - * Create cursor for downloadable item node. - * - * @param string $id Downloadable item ID. - * - * @return string - */ - protected function get_cursor_for_node( $id ) { - return $this->offset_to_cursor( self::PREFIX, $id ); - } - /** * Return an array of items from the query * @@ -213,4 +189,36 @@ public function is_valid_offset( $offset ) { protected function is_valid_model( $model ) { return isset( $model ) && ! empty( $model['download_id'] ); } + + + /** + * Get_offset + * + * This returns the offset to be used in the $query_args based on the $args passed to the + * GraphQL query. + * + * @return int|mixed + */ + public function get_offset() { + /** + * Defaults + */ + $offset = 0; + + /** + * Get the $after offset + */ + if ( ! empty( $this->args['after'] ) ) { + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode + $offset = substr( base64_decode( $this->args['after'] ), strlen( 'arrayconnection:' ) ); + } elseif ( ! empty( $this->args['before'] ) ) { + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode + $offset = substr( base64_decode( $this->args['before'] ), strlen( 'arrayconnection:' ) ); + } + + /** + * Return the higher of the two values + */ + return $offset; + } } diff --git a/includes/data/loader/class-wc-customer-loader.php b/includes/data/loader/class-wc-customer-loader.php index eabf466ad..21891a6d6 100644 --- a/includes/data/loader/class-wc-customer-loader.php +++ b/includes/data/loader/class-wc-customer-loader.php @@ -65,4 +65,22 @@ public function loadKeys( array $keys ) { return $all_customers; } + + /** + * Callback for inject the User dataloader with the WC_Customer model. + * + * @param null $model Possible model instance to be loader. + * @param mixed $entry Data source. + * @param mixed $key Data key/ID. + * @return \WPGraphQL\Model\Model|null + */ + public static function inject_user_loader_models( $model, $entry, $key ) { + if ( is_null( $model ) && is_a( $entry, \WP_User::class ) ) { + if ( in_array( 'customer', (array) $entry->roles, true ) ) { + $model = new Customer( $key ); + } + } + + return $model; + } } diff --git a/tests/_support/Factory/OrderFactory.php b/tests/_support/Factory/OrderFactory.php index 38f39ee66..2d3b189a0 100644 --- a/tests/_support/Factory/OrderFactory.php +++ b/tests/_support/Factory/OrderFactory.php @@ -138,12 +138,12 @@ public function createNew( $args = array(), $items = array() ) { } public function add_line_item( $order, $args = array(), $save = true ) { - $order = \wc_get_order( $order ); + $order = $save ? \wc_get_order( $order ) : $order; if ( empty( $args['product'] ) ) { - $product = wc_get_product( $this->factory->product->create_simple() ); + $product = \wc_get_product( $this->factory->product->createSimple() ); } else { - $product = wc_get_product( $args['product'] ); + $product = \wc_get_product( $args['product'] ); } if ( empty( $args['qty'] ) ) { @@ -157,8 +157,8 @@ public function add_line_item( $order, $args = array(), $save = true ) { array( 'product' => $product, 'quantity' => $qty, - 'subtotal' => wc_get_price_excluding_tax( $product, array( 'qty' => $qty ) ), - 'total' => wc_get_price_excluding_tax( $product, array( 'qty' => $qty ) ), + 'subtotal' => \wc_get_price_excluding_tax( $product, array( 'qty' => $qty ) ), + 'total' => \wc_get_price_excluding_tax( $product, array( 'qty' => $qty ) ), ) ); @@ -177,7 +177,7 @@ public function add_line_item( $order, $args = array(), $save = true ) { } public function add_shipping_line( $order, $args = array(), $save = true ) { - $order = \wc_get_order( $order ); + $order = $save ? \wc_get_order( $order ) : $order; $this->factory->shipping_zone->createLegacyFlatRate(); $item = new WC_Order_Item_Shipping(); diff --git a/tests/_support/Factory/ProductFactory.php b/tests/_support/Factory/ProductFactory.php index 4d43ecac3..a65f50c7a 100644 --- a/tests/_support/Factory/ProductFactory.php +++ b/tests/_support/Factory/ProductFactory.php @@ -313,7 +313,7 @@ public function createDownload( $id = 0 ) { if ( $id ) { $product = \wc_get_product( $id ); - $product->set_downloads( array($download) ); + $product->set_downloads( array( $download ) ); $product->save(); } diff --git a/tests/_support/Helper/crud-helpers/order.php b/tests/_support/Helper/crud-helpers/order.php index f43c29285..907097ff4 100644 --- a/tests/_support/Helper/crud-helpers/order.php +++ b/tests/_support/Helper/crud-helpers/order.php @@ -203,11 +203,9 @@ public function print_query( $id ) { : null, 'pricesIncludeTax' => $data->get_prices_include_tax(), 'parent' => null, - 'customer' => array( - 'id' => ! empty( $data->get_customer_id() ) - ? Relay::toGlobalId( 'customer', $data->get_customer_id() ) - : 'guest', - ), + 'customer' => ! empty( $data->get_customer_id() ) + ? array( 'id' => Relay::toGlobalId( 'customer', $data->get_customer_id() ) ) + : null, 'customerIpAddress' => ! empty( $data->get_customer_ip_address() ) ? $data->get_customer_ip_address() : null, diff --git a/tests/wpunit/CheckoutMutationTest.php b/tests/wpunit/CheckoutMutationTest.php index b7fbf0f3a..18a33cd5c 100644 --- a/tests/wpunit/CheckoutMutationTest.php +++ b/tests/wpunit/CheckoutMutationTest.php @@ -384,10 +384,10 @@ public function testCheckoutMutation() { 'key' => 'test_key', 'value' => 'test value', ), - array( - 'key' => '_new_order_email_sent', - 'value' => 'true' - ) + // array( + // 'key' => '_new_order_email_sent', + // 'value' => 'true' + // ) ), 'couponLines' => array( 'nodes' => array_reverse( diff --git a/tests/wpunit/ConnectionPaginationTest.php b/tests/wpunit/ConnectionPaginationTest.php index 14482dbd9..6ad9322bc 100644 --- a/tests/wpunit/ConnectionPaginationTest.php +++ b/tests/wpunit/ConnectionPaginationTest.php @@ -1,49 +1,23 @@ shop_manager = $this->factory->user->create( array( 'role' => 'shop_manager' ) ); - - // Setup helpers. - $this->coupons = $this->getModule('\Helper\Wpunit')->coupon(); - $this->orders = $this->getModule('\Helper\Wpunit')->order(); - $this->products = $this->getModule('\Helper\Wpunit')->product(); - $this->refunds = $this->getModule('\Helper\Wpunit')->refund(); - $this->customers = $this->getModule('\Helper\Wpunit')->customer(); - } - - public function tearDown(): void { - // your tear down methods here +class ConnectionPaginationTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase { - // then - parent::tearDown(); - } + public function toCursor( $id ) { + if ( $id instanceof \WC_Product_Download ) { + return base64_encode( 'arrayconnection:' . $id['id'] ); + } - public function set_user( $user ) { - wp_set_current_user( $user ); - WC()->customer = new WC_Customer( get_current_user_id(), true ); + return base64_encode( 'arrayconnection:' . $id ); } // tests public function testCouponsPagination() { $coupons = array( - $this->coupons->create(), - $this->coupons->create(), - $this->coupons->create(), - $this->coupons->create(), - $this->coupons->create(), + $this->factory->coupon->create(), + $this->factory->coupon->create(), + $this->factory->coupon->create(), + $this->factory->coupon->create(), + $this->factory->coupon->create(), ); usort( @@ -57,7 +31,7 @@ function( $key_a, $key_b ) { query ($first: Int, $last: Int, $after: String, $before: String) { coupons(first: $first, last: $last, after: $after, before: $before) { nodes { - id + databaseId } pageInfo { hasPreviousPage @@ -69,7 +43,7 @@ function( $key_a, $key_b ) { } '; - $this->set_user( $this->shop_manager ); + $this->loginAsShopManager(); /** * Assertion One @@ -77,67 +51,90 @@ function( $key_a, $key_b ) { * Test "first" parameter. */ $variables = array( 'first' => 2 ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['coupons'] ); - $this->assertNotEmpty( $results['data']['coupons']['pageInfo'] ); - $this->assertTrue( $results['data']['coupons']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['coupons']['pageInfo']['endCursor'] ); - $end_cursor = $results['data']['coupons']['pageInfo']['endCursor']; - - // Check coupons. - $actual = $results['data']['coupons']['nodes']; - $expected = $this->coupons->print_nodes( array_slice( $coupons, 0, 2 ) ); - - $this->assertEquals( $expected, $actual ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'coupons.pageInfo.hasPreviousPage', false ), + $this->expectedObject( 'coupons.pageInfo.hasNextPage', true ), + $this->expectedObject( 'coupons.pageInfo.startCursor', $this->toCursor( $coupons[0] ) ), + $this->expectedObject( 'coupons.pageInfo.endCursor', $this->toCursor( $coupons[1] ) ), + $this->expectedObject( 'coupons.nodes.0.databaseId', $coupons[0] ), + $this->expectedObject( 'coupons.nodes.1.databaseId', $coupons[1] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); /** * Assertion Two * * Test "after" parameter. */ - $variables = array( 'first' => 3, 'after' => $end_cursor ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['coupons'] ); - $this->assertNotEmpty( $results['data']['coupons']['pageInfo'] ); - $this->assertFalse( $results['data']['coupons']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['coupons']['pageInfo']['endCursor'] ); - - // Check coupons. - $actual = $results['data']['coupons']['nodes']; - $expected = $this->coupons->print_nodes( array_slice( $coupons, 2, 3 ) ); - - $this->assertEquals( $expected, $actual ); + $variables = array( + 'first' => 3, + 'after' => $this->toCursor( $coupons[1] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'coupons.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'coupons.pageInfo.hasNextPage', false ), + $this->expectedObject( 'coupons.pageInfo.startCursor', $this->toCursor( $coupons[2] ) ), + $this->expectedObject( 'coupons.pageInfo.endCursor', $this->toCursor( $coupons[4] ) ), + $this->expectedObject( 'coupons.nodes.0.databaseId', $coupons[2] ), + $this->expectedObject( 'coupons.nodes.1.databaseId', $coupons[3] ), + $this->expectedObject( 'coupons.nodes.2.databaseId', $coupons[4] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); + + /** + * Assertion Three + * + * Test "last" parameter. + */ + \WPGraphQL::set_is_graphql_request( true ); + $variables = array( + 'last' => 2, + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'coupons.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'coupons.pageInfo.hasNextPage', false ), + $this->expectedObject( 'coupons.pageInfo.startCursor', $this->toCursor( $coupons[3] ) ), + $this->expectedObject( 'coupons.pageInfo.endCursor', $this->toCursor( $coupons[4] ) ), + $this->expectedObject( 'coupons.nodes.0.databaseId', $coupons[3] ), + $this->expectedObject( 'coupons.nodes.1.databaseId', $coupons[4] ), + ); + + //$this->assertQuerySuccessful( $response, $expected ); + + /** + * Assertion Four + * + * Test "before" parameter. + */ + $variables = array( + 'last' => 2, + 'before' => $this->toCursor( $coupons[3] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'coupons.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'coupons.pageInfo.hasNextPage', true ), + $this->expectedObject( 'coupons.pageInfo.startCursor', $this->toCursor( $coupons[1] ) ), + $this->expectedObject( 'coupons.pageInfo.endCursor', $this->toCursor( $coupons[2] ) ), + $this->expectedObject( 'coupons.nodes.0.databaseId', $coupons[1] ), + $this->expectedObject( 'coupons.nodes.1.databaseId', $coupons[2] ), + ); + + //$this->assertQuerySuccessful( $response, $expected ); } public function testProductsPagination() { $products = array( - $this->products->create_simple(), - $this->products->create_simple(), - $this->products->create_simple(), - $this->products->create_simple(), - $this->products->create_simple(), + $this->factory->product->createSimple(), + $this->factory->product->createSimple(), + $this->factory->product->createSimple(), + $this->factory->product->createSimple(), + $this->factory->product->createSimple(), ); usort( @@ -151,7 +148,7 @@ function( $key_a, $key_b ) { query ($first: Int, $last: Int, $after: String, $before: String) { products(first: $first, last: $last, after: $after, before: $before) { nodes { - id + databaseId } pageInfo { hasPreviousPage @@ -169,77 +166,97 @@ function( $key_a, $key_b ) { * Test "first" parameter. */ $variables = array( 'first' => 2 ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['products'] ); - $this->assertNotEmpty( $results['data']['products']['pageInfo'] ); - $this->assertTrue( $results['data']['products']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['products']['pageInfo']['endCursor'] ); - $end_cursor = $results['data']['products']['pageInfo']['endCursor']; - - // Check products. - $actual = $results['data']['products']['nodes']; - $expected = $this->products->print_nodes( array_slice( $products, 0, 2 ) ); - - $this->assertEquals( $expected, $actual ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'products.pageInfo.hasPreviousPage', false ), + $this->expectedObject( 'products.pageInfo.hasNextPage', true ), + $this->expectedObject( 'products.pageInfo.startCursor', $this->toCursor( $products[0] ) ), + $this->expectedObject( 'products.pageInfo.endCursor', $this->toCursor( $products[1] ) ), + $this->expectedObject( 'products.nodes.0.databaseId', $products[0] ), + $this->expectedObject( 'products.nodes.1.databaseId', $products[1] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); /** * Assertion Two * * Test "after" parameter. */ - $variables = array( 'first' => 3, 'after' => $end_cursor ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['products'] ); - $this->assertNotEmpty( $results['data']['products']['pageInfo'] ); - $this->assertFalse( $results['data']['products']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['products']['pageInfo']['endCursor'] ); - - // Check coupons. - $actual = $results['data']['products']['nodes']; - $expected = $this->products->print_nodes( array_slice( $products, 2, 3 ) ); - - $this->assertEquals( $expected, $actual ); + $variables = array( + 'first' => 3, + 'after' => $this->toCursor( $products[1] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'products.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'products.pageInfo.hasNextPage', false ), + $this->expectedObject( 'products.pageInfo.startCursor', $this->toCursor( $products[2] ) ), + $this->expectedObject( 'products.pageInfo.endCursor', $this->toCursor( $products[4] ) ), + $this->expectedObject( 'products.nodes.0.databaseId', $products[2] ), + $this->expectedObject( 'products.nodes.1.databaseId', $products[3] ), + $this->expectedObject( 'products.nodes.2.databaseId', $products[4] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); + + /** + * Assertion Three + * + * Test "last" parameter. + */ + $variables = array( 'last' => 2 ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'products.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'products.pageInfo.hasNextPage', false ), + $this->expectedObject( 'products.pageInfo.startCursor', $this->toCursor( $products[3] ) ), + $this->expectedObject( 'products.pageInfo.endCursor', $this->toCursor( $products[4] ) ), + $this->expectedObject( 'products.nodes.0.databaseId', $products[3] ), + $this->expectedObject( 'products.nodes.1.databaseId', $products[4] ), + ); + + //$this->assertQuerySuccessful( $response, $expected ); + + /** + * Assertion Four + * + * Test "before" parameter. + */ + $variables = array( + 'last' => 2, + 'before' => $this->toCursor( $products[3] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'products.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'products.pageInfo.hasNextPage', true ), + $this->expectedObject( 'products.pageInfo.startCursor', $this->toCursor( $products[1] ) ), + $this->expectedObject( 'products.pageInfo.endCursor', $this->toCursor( $products[2] ) ), + $this->expectedObject( 'products.nodes.0.databaseId', $products[1] ), + $this->expectedObject( 'products.nodes.1.databaseId', $products[2] ), + ); + + //$this->assertQuerySuccessful( $response, $expected ); } public function testOrdersPagination() { - wp_set_current_user( $this->shop_manager ); + $this->loginAsShopManager(); $query = new \WC_Order_Query(); $old_orders = $query->get_orders(); foreach ( $old_orders as $order ) { - $this->orders->delete_order( $order ); + $order->delete_order( $order ); } unset( $old_orders ); unset( $query ); $orders = array( - $this->orders->create(), - $this->orders->create(), - $this->orders->create(), - $this->orders->create(), - $this->orders->create(), + $this->factory->order->createNew(), + $this->factory->order->createNew(), + $this->factory->order->createNew(), + $this->factory->order->createNew(), + $this->factory->order->createNew(), ); usort( @@ -253,7 +270,7 @@ function( $key_a, $key_b ) { query ($first: Int, $last: Int, $after: String, $before: String) { orders(first: $first, last: $last, after: $after, before: $before) { nodes { - id + databaseId } pageInfo { hasPreviousPage @@ -271,68 +288,88 @@ function( $key_a, $key_b ) { * Test "first" parameter. */ $variables = array( 'first' => 2 ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['orders'] ); - $this->assertNotEmpty( $results['data']['orders']['pageInfo'] ); - $this->assertTrue( $results['data']['orders']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['orders']['pageInfo']['endCursor'] ); - $end_cursor = $results['data']['orders']['pageInfo']['endCursor']; - - // Check orders. - $actual = $results['data']['orders']['nodes']; - $expected = $this->orders->print_nodes( array_slice( $orders, 0, 2 ) ); - - $this->assertEquals( $expected, $actual ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'orders.pageInfo.hasPreviousPage', false ), + $this->expectedObject( 'orders.pageInfo.hasNextPage', true ), + $this->expectedObject( 'orders.pageInfo.startCursor', $this->toCursor( $orders[0] ) ), + $this->expectedObject( 'orders.pageInfo.endCursor', $this->toCursor( $orders[1] ) ), + $this->expectedObject( 'orders.nodes.0.databaseId', $orders[0] ), + $this->expectedObject( 'orders.nodes.1.databaseId', $orders[1] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); /** * Assertion Two * * Test "after" parameter. */ - $variables = array( 'first' => 3, 'after' => $end_cursor ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['orders'] ); - $this->assertNotEmpty( $results['data']['orders']['pageInfo'] ); - $this->assertFalse( $results['data']['orders']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['orders']['pageInfo']['endCursor'] ); - - // Check orders. - $actual = $results['data']['orders']['nodes']; - $expected = $this->orders->print_nodes( array_slice( $orders, 2, 3 ) ); + $variables = array( + 'first' => 3, + 'after' => $this->toCursor( $orders[1] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'orders.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'orders.pageInfo.hasNextPage', false ), + $this->expectedObject( 'orders.pageInfo.startCursor', $this->toCursor( $orders[2] ) ), + $this->expectedObject( 'orders.pageInfo.endCursor', $this->toCursor( $orders[4] ) ), + $this->expectedObject( 'orders.nodes.0.databaseId', $orders[2] ), + $this->expectedObject( 'orders.nodes.1.databaseId', $orders[3] ), + $this->expectedObject( 'orders.nodes.2.databaseId', $orders[4] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); + + /** + * Assertion Three + * + * Test "last" parameter. + */ + $variables = array( 'last' => 2 ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'orders.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'orders.pageInfo.hasNextPage', false ), + $this->expectedObject( 'orders.pageInfo.startCursor', $this->toCursor( $orders[3] ) ), + $this->expectedObject( 'orders.pageInfo.endCursor', $this->toCursor( $orders[4] ) ), + $this->expectedObject( 'orders.nodes.0.databaseId', $orders[3] ), + $this->expectedObject( 'orders.nodes.1.databaseId', $orders[4] ), + ); + + //$this->assertQuerySuccessful( $response, $expected ); - $this->assertEquals( $expected, $actual ); + /** + * Assertion Four + * + * Test "before" parameter. + */ + $variables = array( + 'last' => 2, + 'before' => $this->toCursor( $orders[3] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'orders.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'orders.pageInfo.hasNextPage', true ), + $this->expectedObject( 'orders.pageInfo.startCursor', $this->toCursor( $orders[1] ) ), + $this->expectedObject( 'orders.pageInfo.endCursor', $this->toCursor( $orders[2] ) ), + $this->expectedObject( 'orders.nodes.0.databaseId', $orders[1] ), + $this->expectedObject( 'orders.nodes.1.databaseId', $orders[2] ), + ); + + //$this->assertQuerySuccessful( $response, $expected ); } public function testRefundsPagination() { - $order = $this->orders->create(); + $order = $this->factory->order->createNew(); $refunds = array( - $this->refunds->create( $order, array( 'amount' => 0.5 ) ), - $this->refunds->create( $order, array( 'amount' => 0.5 ) ), - $this->refunds->create( $order, array( 'amount' => 0.5 ) ), - $this->refunds->create( $order, array( 'amount' => 0.5 ) ), - $this->refunds->create( $order, array( 'amount' => 0.5 ) ), + $this->factory->refund->createNew( $order, array( 'amount' => 0.5 ) ), + $this->factory->refund->createNew( $order, array( 'amount' => 0.5 ) ), + $this->factory->refund->createNew( $order, array( 'amount' => 0.5 ) ), + $this->factory->refund->createNew( $order, array( 'amount' => 0.5 ) ), + $this->factory->refund->createNew( $order, array( 'amount' => 0.5 ) ), ); usort( @@ -346,7 +383,7 @@ function( $key_a, $key_b ) { query ($first: Int, $last: Int, $after: String, $before: String) { refunds(first: $first, last: $last, after: $after, before: $before) { nodes { - id + databaseId } pageInfo { hasPreviousPage @@ -358,7 +395,7 @@ function( $key_a, $key_b ) { } '; - wp_set_current_user( $this->shop_manager ); + $this->loginAsShopManager(); /** * Assertion One @@ -366,81 +403,106 @@ function( $key_a, $key_b ) { * Test "first" parameter. */ $variables = array( 'first' => 2 ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['refunds'] ); - $this->assertNotEmpty( $results['data']['refunds']['pageInfo'] ); - $this->assertTrue( $results['data']['refunds']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['refunds']['pageInfo']['endCursor'] ); - $end_cursor = $results['data']['refunds']['pageInfo']['endCursor']; - - // Check refunds. - $actual = $results['data']['refunds']['nodes']; - $expected = $this->refunds->print_nodes( array_slice( $refunds, 0, 2 ) ); - - $this->assertEquals( $expected, $actual ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'refunds.pageInfo.hasPreviousPage', false ), + $this->expectedObject( 'refunds.pageInfo.hasNextPage', true ), + $this->expectedObject( 'refunds.pageInfo.startCursor', $this->toCursor( $refunds[0] ) ), + $this->expectedObject( 'refunds.pageInfo.endCursor', $this->toCursor( $refunds[1] ) ), + $this->expectedObject( 'refunds.nodes.0.databaseId', $refunds[0] ), + $this->expectedObject( 'refunds.nodes.1.databaseId', $refunds[1] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); /** * Assertion Two * * Test "after" parameter. */ - $variables = array( 'first' => 3, 'after' => $end_cursor ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['refunds'] ); - $this->assertNotEmpty( $results['data']['refunds']['pageInfo'] ); - $this->assertFalse( $results['data']['refunds']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['refunds']['pageInfo']['endCursor'] ); - - // Check refunds. - $actual = $results['data']['refunds']['nodes']; - $expected = $this->refunds->print_nodes( array_slice( $refunds, 2, 3 ) ); + $variables = array( + 'first' => 3, + 'after' => $this->toCursor( $refunds[1] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'refunds.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'refunds.pageInfo.hasNextPage', false ), + $this->expectedObject( 'refunds.pageInfo.startCursor', $this->toCursor( $refunds[2] ) ), + $this->expectedObject( 'refunds.pageInfo.endCursor', $this->toCursor( $refunds[4] ) ), + $this->expectedObject( 'refunds.nodes.0.databaseId', $refunds[2] ), + $this->expectedObject( 'refunds.nodes.1.databaseId', $refunds[3] ), + $this->expectedObject( 'refunds.nodes.2.databaseId', $refunds[4] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); + + /** + * Assertion Three + * + * Test "last" parameter. + */ + $variables = array( 'last' => 2 ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'refunds.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'refunds.pageInfo.hasNextPage', false ), + $this->expectedObject( 'refunds.pageInfo.startCursor', $this->toCursor( $refunds[3] ) ), + $this->expectedObject( 'refunds.pageInfo.endCursor', $this->toCursor( $refunds[4] ) ), + $this->expectedObject( 'refunds.nodes.0.databaseId', $refunds[3] ), + $this->expectedObject( 'refunds.nodes.1.databaseId', $refunds[4] ), + ); + + //$this->assertQuerySuccessful( $response, $expected ); - $this->assertEquals( $expected, $actual ); + /** + * Assertion Four + * + * Test "before" parameter. + */ + $variables = array( + 'last' => 2, + 'before' => $this->toCursor( $refunds[3] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'refunds.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'refunds.pageInfo.hasNextPage', true ), + $this->expectedObject( 'refunds.pageInfo.startCursor', $this->toCursor( $refunds[1] ) ), + $this->expectedObject( 'refunds.pageInfo.endCursor', $this->toCursor( $refunds[2] ) ), + $this->expectedObject( 'refunds.nodes.0.databaseId', $refunds[1] ), + $this->expectedObject( 'refunds.nodes.1.databaseId', $refunds[2] ), + ); + + //$this->assertQuerySuccessful( $response, $expected ); } public function testCustomersPagination() { - $customers = array( - $this->customers->create(), - $this->customers->create(), - $this->customers->create(), - $this->customers->create(), - $this->customers->create(), + $some_customers = array( + $this->factory->customer->create(), + $this->factory->customer->create(), + $this->factory->customer->create(), + $this->factory->customer->create(), + $this->factory->customer->create(), ); - usort( - $customers, - function( $key_a, $key_b ) { - return $key_a < $key_b; - } - ); + $customers = get_users( + array( + 'fields' => 'id', + 'role' => 'customer', + 'orderby' => 'user_login', + 'order' => 'ASC', + ) + ); + + $customers = array_map( 'absint', $customers ); $query = ' query ($first: Int, $last: Int, $after: String, $before: String) { customers(first: $first, last: $last, after: $after, before: $before) { nodes { - id + databaseId + username } pageInfo { hasPreviousPage @@ -452,104 +514,111 @@ function( $key_a, $key_b ) { } '; - wp_set_current_user( $this->shop_manager ); + $this->loginAsShopManager(); /** - * Assertion One - * - * Test "first" parameter. - */ + * Assertion One + * + * Test "first" parameter. + */ $variables = array( 'first' => 2 ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['customers'] ); - $this->assertNotEmpty( $results['data']['customers']['pageInfo'] ); - $this->assertTrue( $results['data']['customers']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['customers']['pageInfo']['endCursor'] ); - $end_cursor = $results['data']['customers']['pageInfo']['endCursor']; - - // Check customers. - $actual = $results['data']['customers']['nodes']; - $expected = $this->customers->print_nodes( array_slice( $customers, 0, 2 ) ); - - $this->assertEquals( $expected, $actual ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'customers.pageInfo.hasPreviousPage', false ), + $this->expectedObject( 'customers.pageInfo.hasNextPage', true ), + $this->expectedObject( 'customers.nodes.0.databaseId', $customers[0] ), + $this->expectedObject( 'customers.nodes.1.databaseId', $customers[1] ), + $this->expectedObject( 'customers.pageInfo.startCursor', $this->toCursor( $customers[0] ) ), + $this->expectedObject( 'customers.pageInfo.endCursor', $this->toCursor( $customers[1] ) ), + ); + + $this->assertQuerySuccessful( $response, $expected ); /** - * Assertion Two - * - * Test "after" parameter. - */ - $variables = array( 'first' => 3, 'after' => $end_cursor ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['customers'] ); - $this->assertNotEmpty( $results['data']['customers']['pageInfo'] ); - $this->assertFalse( $results['data']['customers']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['customers']['pageInfo']['endCursor'] ); - - // Check customers. - $actual = $results['data']['customers']['nodes']; - $expected = $this->customers->print_nodes( array_slice( $customers, 2, 3 ) ); + * Assertion Two + * + * Test "after" parameter. + */ + $variables = array( + 'first' => 3, + 'after' => $this->toCursor( $customers[1] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'customers.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'customers.pageInfo.startCursor', $this->toCursor( $customers[2] ) ), + $this->expectedObject( 'customers.pageInfo.endCursor', $this->toCursor( $customers[4] ) ), + $this->expectedObject( 'customers.nodes.0.databaseId', $customers[2] ), + $this->expectedObject( 'customers.nodes.1.databaseId', $customers[3] ), + $this->expectedObject( 'customers.nodes.2.databaseId', $customers[4] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); + + /** + * Assertion Three + * + * Test "last" parameter. + */ + $variables = array( 'last' => 2 ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'customers.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'customers.pageInfo.hasNextPage', false ), + $this->expectedObject( 'customers.pageInfo.startCursor', $this->toCursor( $customers[3] ) ), + $this->expectedObject( 'customers.pageInfo.endCursor', $this->toCursor( $customers[4] ) ), + $this->expectedObject( 'customers.nodes.0.databaseId', $customers[3] ), + $this->expectedObject( 'customers.nodes.1.databaseId', $customers[4] ), + ); + + //$this->assertQuerySuccessful( $response, $expected ); - $this->assertEquals( $expected, $actual ); + /** + * Assertion Four + * + * Test "before" parameter. + */ + $variables = array( + 'last' => 2, + 'before' => $this->toCursor( $customers[3] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'customers.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'customers.pageInfo.hasNextPage', true ), + $this->expectedObject( 'customers.pageInfo.startCursor', $this->toCursor( $customers[1] ) ), + $this->expectedObject( 'customers.pageInfo.endCursor', $this->toCursor( $customers[2] ) ), + $this->expectedObject( 'customers.nodes.0.databaseId', $customers[1] ), + $this->expectedObject( 'customers.nodes.1.databaseId', $customers[2] ), + ); + + //$this->assertQuerySuccessful( $response, $expected ); } public function testDownloadableItemsPagination() { - $customer_id = $this->customers->create(); - $downloable_products = array( - $this->products->create_simple( - array( - 'downloadable' => true, - 'downloads' => array( $this->products->create_download() ) - ) - ), - $this->products->create_simple( - array( - 'downloadable' => true, - 'downloads' => array( $this->products->create_download() ) - ) - ), - $this->products->create_simple( - array( - 'downloadable' => true, - 'downloads' => array( $this->products->create_download() ) - ) - ), - $this->products->create_simple( - array( - 'downloadable' => true, - 'downloads' => array( $this->products->create_download() ) - ) - ), - $this->products->create_simple( - array( - 'downloadable' => true, - 'downloads' => array( $this->products->create_download() ) - ) - ), - ); - - $order_id = $this->orders->create( + $customer_id = $this->factory->customer->create(); + + $downloads = array( + $this->factory->product->createDownload(), + $this->factory->product->createDownload(), + $this->factory->product->createDownload(), + $this->factory->product->createDownload(), + $this->factory->product->createDownload(), + + ); + $products = array_map( + function( $download ) { + return $this->factory->product->createSimple( + array( + 'downloadable' => true, + 'downloads' => array( $download ) + ) + ); + }, + $downloads + ); + + $order_id = $this->factory->order->createNew( array( 'status' => 'completed', 'customer_id' => $customer_id, @@ -562,11 +631,13 @@ function( $product_id ) { 'qty' => 1, ); }, - $downloable_products + $products ), ) ); + $order = \wc_get_order( $order_id ); + // Force download permission updated. wc_downloadable_product_permissions( $order_id, true ); @@ -595,83 +666,86 @@ function( $product_id ) { } '; - $this->set_user( $customer_id ); + $this->loginAs( $customer_id ); - /** - * Assertion One - * - * Test "first" parameter. - */ + /** + * Assertion One + * + * Test "first" parameter. + */ $variables = array( 'first' => 2 ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['customer'] ); - $this->assertNotEmpty( $results['data']['customer']['orders'] ); - $this->assertNotEmpty( $results['data']['customer']['orders']['nodes'] ); - $this->assertNotEmpty( $results['data']['customer']['orders']['nodes'][0] ); - $this->assertNotEmpty( $results['data']['customer']['orders']['nodes'][0]['downloadableItems'] ); - $this->assertNotEmpty( $results['data']['customer']['orders']['nodes'][0]['downloadableItems']['pageInfo'] ); - $this->assertTrue( $results['data']['customer']['orders']['nodes'][0]['downloadableItems']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['customer']['orders']['nodes'][0]['downloadableItems']['pageInfo']['endCursor'] ); - $end_cursor = $results['data']['customer']['orders']['nodes'][0]['downloadableItems']['pageInfo']['endCursor']; - - // Check downloadable items. - $actual = $results['data']['customer']['orders']['nodes'][0]['downloadableItems']['nodes']; - $expected = array_map( - function( $product_id ) { - return array( 'product' => array( 'databaseId' => $product_id ) ); - }, - array_slice( $downloable_products, 0, 2 ) - ); - - $this->assertEquals( $expected, $actual ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.hasPreviousPage', false ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.hasNextPage', true ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.startCursor', $this->toCursor( $downloads[0] ) ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.endCursor', $this->toCursor( $downloads[1] ) ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.nodes.0.product.databaseId', $products[0] ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.nodes.1.product.databaseId', $products[1] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); /** - * Assertion Two - * - * Test "after" parameter. - */ - $variables = array( 'first' => 3, 'after' => $end_cursor ); - $results = graphql( - array( - 'query' => $query, - 'variables' => $variables, - ) - ); - - // use --debug flag to view. - codecept_debug( $results ); - - // Check pageInfo. - $this->assertNotEmpty( $results['data'] ); - $this->assertNotEmpty( $results['data']['customer'] ); - $this->assertNotEmpty( $results['data']['customer']['orders'] ); - $this->assertNotEmpty( $results['data']['customer']['orders']['nodes'] ); - $this->assertNotEmpty( $results['data']['customer']['orders']['nodes'][0] ); - $this->assertNotEmpty( $results['data']['customer']['orders']['nodes'][0]['downloadableItems'] ); - $this->assertNotEmpty( $results['data']['customer']['orders']['nodes'][0]['downloadableItems']['pageInfo'] ); - $this->assertFalse( $results['data']['customer']['orders']['nodes'][0]['downloadableItems']['pageInfo']['hasNextPage'] ); - $this->assertNotEmpty( $results['data']['customer']['orders']['nodes'][0]['downloadableItems']['pageInfo']['endCursor'] ); - - // Check downloadable items. - $actual = $results['data']['customer']['orders']['nodes'][0]['downloadableItems']['nodes']; - $expected = array_map( - function( $product_id ) { - return array( 'product' => array( 'databaseId' => $product_id ) ); - }, - array_slice( $downloable_products, 2, 3 ) - ); + * Assertion Two + * + * Test "after" parameter. + */ + $variables = array( + 'first' => 3, + 'after' => $this->toCursor( $downloads[1] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.hasNextPage', false ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.startCursor', $this->toCursor( $downloads[2] ) ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.endCursor', $this->toCursor( $downloads[4] ) ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.nodes.0.product.databaseId', $products[2] ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.nodes.1.product.databaseId', $products[3] ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.nodes.2.product.databaseId', $products[4] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); + + /** + * Assertion Three + * + * Test "last" parameter. + */ + $variables = array( 'last' => 2 ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.hasPreviousPage', true ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.hasNextPage', false ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.startCursor', $this->toCursor( $downloads[3] ) ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.endCursor', $this->toCursor( $downloads[4] ) ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.nodes.0.product.databaseId', $products[3] ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.nodes.1.product.databaseId', $products[4] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); - $this->assertEquals( $expected, $actual ); + /** + * Assertion Two + * + * Test "before" parameter. + */ + $variables = array( + 'last' => 3, + 'before' => $this->toCursor( $downloads[3] ), + ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.hasPreviousPage', false ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.hasNextPage', true ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.startCursor', $this->toCursor( $downloads[0] ) ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.pageInfo.endCursor', $this->toCursor( $downloads[2] ) ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.nodes.0.product.databaseId', $products[0] ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.nodes.1.product.databaseId', $products[1] ), + $this->expectedObject( 'customer.orders.nodes.0.downloadableItems.nodes.2.product.databaseId', $products[2] ), + ); + + $this->assertQuerySuccessful( $response, $expected ); } } diff --git a/tests/wpunit/CustomerQueriesTest.php b/tests/wpunit/CustomerQueriesTest.php index 2fb72747c..02962fd61 100644 --- a/tests/wpunit/CustomerQueriesTest.php +++ b/tests/wpunit/CustomerQueriesTest.php @@ -1,36 +1,73 @@ shop_manager = $this->factory->user->create( array( 'role' => 'shop_manager', 'user_login' => 'shopManager25' ) ); - $this->customer = $this->factory->user->create( array( 'role' => 'customer', 'user_login' => 'customer43' ) ); - $this->helper = $this->getModule('\Helper\Wpunit')->customer(); - $this->order_helper = $this->getModule('\Helper\Wpunit')->order(); - $this->new_customer = $this->helper->create(); - } - - public function tearDown(): void { - // your tear down methods here - // then - parent::tearDown(); - } - - public function set_user( $user ) { - wp_set_current_user( $user ); - WC()->customer = new WC_Customer( get_current_user_id(), true ); +class CustomerQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase { + + public function expectedCustomerData( $id ) { + $customer = new \WC_Customer( $id ); + $wp_user = get_user_by( 'ID', $id ); + + if ( ! $customer->get_id() ) { + throw new \Exception( 'Invalid customer ID provided.' ); + } + + return array( + $this->expectedObject( 'customer.id', $this->toRelayId( 'customer', $id ) ), + $this->expectedObject( 'customer.databaseId', $id ), + $this->expectedObject( 'customer.isVatExempt', $customer->get_is_vat_exempt() ), + $this->expectedObject( 'customer.hasCalculatedShipping', $customer->has_calculated_shipping() ), + $this->expectedObject( 'customer.calculatedShipping', $customer->get_calculated_shipping() ), + $this->expectedObject( 'customer.orderCount', $customer->get_order_count() ), + $this->expectedObject( 'customer.totalSpent', (float) $customer->get_total_spent() ), + $this->expectedObject( 'customer.username', $customer->get_username() ), + $this->expectedObject( 'customer.email', $customer->get_email() ), + $this->expectedObject( 'customer.firstName', $this->maybe( $customer->get_first_name() ) ), + $this->expectedObject( 'customer.lastName', $this->maybe( $customer->get_last_name() ) ), + $this->expectedObject( 'customer.displayName', $customer->get_display_name() ), + $this->expectedObject( 'customer.role', $customer->get_role() ), + $this->expectedObject( 'customer.date', (string) $customer->get_date_created() ), + $this->expectedObject( 'customer.modified', (string) $customer->get_date_modified() ), + $this->expectedObject( 'customer.lastOrder.databaseId', $customer->get_last_order() ? $customer->get_last_order()->get_id() : null ), + $this->expectedObject( 'customer.billing.firstName', $this->maybe( $customer->get_billing_first_name() ) ), + $this->expectedObject( 'customer.billing.lastName', $this->maybe( $customer->get_billing_last_name() ) ), + $this->expectedObject( 'customer.billing.company', $this->maybe( $customer->get_billing_company() ) ), + $this->expectedObject( 'customer.billing.address1', $this->maybe( $customer->get_billing_address_1() ) ), + $this->expectedObject( 'customer.billing.address2', $this->maybe( $customer->get_billing_address_2() ) ), + $this->expectedObject( 'customer.billing.city', $this->maybe( $customer->get_billing_city() ) ), + $this->expectedObject( 'customer.billing.state', $this->maybe( $customer->get_billing_state() ) ), + $this->expectedObject( 'customer.billing.postcode', $this->maybe( $customer->get_billing_postcode() ) ), + $this->expectedObject( 'customer.billing.country', $this->maybe( $customer->get_billing_country() ) ), + $this->expectedObject( 'customer.billing.email', $this->maybe( $customer->get_billing_email() ) ), + $this->expectedObject( 'customer.billing.phone', $this->maybe( $customer->get_billing_phone() ) ), + $this->expectedObject( 'customer.shipping.firstName', $this->maybe( $customer->get_shipping_first_name() ) ), + $this->expectedObject( 'customer.shipping.lastName', $this->maybe( $customer->get_shipping_last_name() ) ), + $this->expectedObject( 'customer.shipping.company', $this->maybe( $customer->get_shipping_company() ) ), + $this->expectedObject( 'customer.shipping.address1', $this->maybe( $customer->get_shipping_address_1() ) ), + $this->expectedObject( 'customer.shipping.address2', $this->maybe( $customer->get_shipping_address_2() ) ), + $this->expectedObject( 'customer.shipping.city', $this->maybe( $customer->get_shipping_city() ) ), + $this->expectedObject( 'customer.shipping.state', $this->maybe( $customer->get_shipping_state() ) ), + $this->expectedObject( 'customer.shipping.postcode', $this->maybe( $customer->get_shipping_postcode() ) ), + $this->expectedObject( 'customer.shipping.country', $this->maybe( $customer->get_shipping_country() ) ), + $this->expectedObject( 'customer.isPayingCustomer', $customer->get_is_paying_customer() ), + $this->expectedObject( + 'customer.jwtAuthToken', + ! is_wp_error( \WPGraphQL\JWT_Authentication\Auth::get_token( $wp_user ) ) + ? \WPGraphQL\JWT_Authentication\Auth::get_token( $wp_user ) + : null + ), + $this->expectedObject( + 'customer.jwtRefreshToken', + ! is_wp_error( \WPGraphQL\JWT_Authentication\Auth::get_refresh_token( $wp_user ) ) + ? \WPGraphQL\JWT_Authentication\Auth::get_refresh_token( $wp_user ) + : null + ), + ); } // tests public function testCustomerQueryAndArgs() { + $new_customer_id = $this->factory->customer->create(); + $query = ' query ( $id: ID, $customerId: Int ) { customer( id: $id, customerId: $customerId ) { @@ -89,36 +126,33 @@ public function testCustomerQueryAndArgs() { * * Query should return null value due to lack of permissions. */ - $this->set_user( $this->customer ); - $variables = array( 'id' => Relay::toGlobalId( 'customer', $this->new_customer ) ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); + $this->loginAsCustomer(); + $variables = array( 'id' => $this->toRelayId( 'customer', $new_customer_id ) ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedErrorPath( 'customer' ), + $this->expectedObject( 'customer', 'null' ) + ); - // use --debug flag to view. - codecept_debug( $actual ); + $this->assertQueryError( $response, $expected ); - $this->assertNotEmpty( $actual['data'] ); - $this->assertNotEmpty( $actual['errors'] ); - $this->assertNull( $actual['data']['customer'] ); // Clear customer cache. - $this->getModule('\Helper\Wpunit')->clear_loader_cache( 'wc_customer' ); + $this->clearLoaderCache( 'wc_customer' ); /** * Assertion Two * * Query should return requested data because user queried themselves. */ - $variables = array( 'id' => Relay::toGlobalId( 'customer', $this->customer ) ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); - $expected = array( 'data' => array( 'customer' => $this->helper->print_query( $this->customer ) ) ); + $variables = array( 'id' => $this->toRelayId( 'customer', $this->customer ) ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = $this->expectedCustomerData( $this->customer ); - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); + $this->assertQuerySuccessful( $response, $expected ); // Clear customer cache. - $this->getModule('\Helper\Wpunit')->clear_loader_cache( 'wc_customer' ); + $this->clearLoaderCache( 'wc_customer' ); /** * Assertion Three @@ -126,81 +160,82 @@ public function testCustomerQueryAndArgs() { * Query should return requested data because has sufficient permissions, * but should not have access to JWT fields. */ - $this->set_user( $this->shop_manager ); - $variables = array( 'id' => Relay::toGlobalId( 'customer', $this->new_customer ) ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); - $expected = array( 'data' => array( 'customer' => $this->helper->print_query( $this->new_customer ) ) ); - - // use --debug flag to view. - codecept_debug( $actual ); + $this->loginAsShopManager(); + $variables = array( 'id' => $this->toRelayId( 'customer', $new_customer_id ) ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array_merge( + array( + $this->expectedErrorPath( 'customer.jwtAuthToken' ), + $this->expectedObject( 'customer.jwtAuthToken', 'null' ), + $this->expectedErrorPath( 'customer.jwtRefreshToken' ), + $this->expectedObject( 'customer.jwtRefreshToken', 'null' ) + ), + $this->expectedCustomerData( $new_customer_id ) + ); - $this->assertEquals( $expected['data'], $actual['data'] ); - $this->assertNotEmpty( $actual['errors'] ); + $this->assertQueryError( $response, $expected ); // Clear customer cache. - $this->getModule('\Helper\Wpunit')->clear_loader_cache( 'wc_customer' ); + $this->clearLoaderCache( 'wc_customer' ); /** * Assertion Four * * Query should return data corresponding with current user when no ID is provided. */ - $this->set_user( $this->new_customer ); - $actual = graphql( array( 'query' => $query ) ); - $expected = array( 'data' => array( 'customer' => $this->helper->print_query( $this->new_customer, true ) ) ); - - // use --debug flag to view. - codecept_debug( $actual ); + $this->loginAs( $new_customer_id ); + $response = $this->graphql( compact( 'query' ) ); + $expected = $this->expectedCustomerData( $new_customer_id ); - $this->assertEquals( $expected, $actual ); + $this->assertQuerySuccessful( $response, $expected ); // Clear customer cache. - $this->getModule('\Helper\Wpunit')->clear_loader_cache( 'wc_customer' ); + $this->clearLoaderCache( 'wc_customer' ); /** * Assertion Five * * Query should return requested data because user queried themselves. */ - $this->set_user( $this->new_customer ); - $variables = array( 'customerId' => $this->new_customer ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); - $expected = array( 'data' => array( 'customer' => $this->helper->print_query( $this->new_customer ) ) ); + $this->loginAs( $new_customer_id ); + $variables = array( 'customerId' => $new_customer_id ); + $response = $this->graphql( compact( 'query', 'variables' ) ); - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); + $this->assertQuerySuccessful( $response, $expected ); // Clear customer cache. - $this->getModule('\Helper\Wpunit')->clear_loader_cache( 'wc_customer' ); + $this->clearLoaderCache( 'wc_customer' ); /** * Assertion Six * * Query should return null value due to lack of permissions.. */ - $this->set_user( $this->customer ); - $variables = array( 'customerId' => $this->new_customer ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); + $this->loginAsCustomer(); + $variables = array( 'customerId' => $new_customer_id ); + $response = $this->graphql( compact( 'query', 'variables' ) ); + $expected = array( + $this->expectedErrorPath( 'customer' ), + $this->expectedObject( 'customer', 'null' ) + ); - // use --debug flag to view. - codecept_debug( $actual ); + $this->assertQueryError( $response, $expected ); - $this->assertNotEmpty( $actual['data'] ); - $this->assertNotEmpty( $actual['errors'] ); - $this->assertNull( $actual['data']['customer'] ); + // Clear customer cache. + $this->clearLoaderCache( 'wc_customer' ); } public function testCustomersQueryAndWhereArgs() { - $user_id = $this->helper->create( array( 'email' => 'gotcha@example.com', 'username' => 'megaman8080' ) ); - $users = get_users( - array ( - 'count_total' => false, - 'order' => 'ASC', - 'fields' => 'ID', - 'role' => 'customer', - ) + $users = array( + $this->factory->customer->create( + array( + 'email' => 'gotcha@example.com', + 'username' => 'megaman8080' + ) + ), + $this->factory->customer->create(), + $this->factory->customer->create(), + $this->factory->customer->create(), ); $query = ' @@ -209,9 +244,6 @@ public function testCustomersQueryAndWhereArgs() { $include: [Int], $exclude: [Int], $email: String, - $role: UserRoleEnum, - $roleIn: [UserRoleEnum], - $roleNotIn: [UserRoleEnum], $orderby: CustomerConnectionOrderbyEnum, $order: OrderEnum ) { @@ -220,14 +252,11 @@ public function testCustomersQueryAndWhereArgs() { include: $include, exclude: $exclude, email: $email, - role: $role, - roleIn: $roleIn, - roleNotIn: $roleNotIn, orderby: $orderby, order: $order } ) { nodes{ - id + databaseId } } } @@ -238,37 +267,27 @@ public function testCustomersQueryAndWhereArgs() { * * Query should return null value due to lack of capabilities... */ - $this->set_user( $this->customer ); - $actual = graphql( array( 'query' => $query ) ); - $expected = array( 'data' => array( 'customers' => array( 'nodes' => array() ) ) ); + $this->loginAs( $users[0] ); + $response = $this->graphql( compact( 'query' ) ); + $expected = array( $this->expectedObject( 'customers.nodes', array() ) ); - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); - - // Clear customer cache. - $this->getModule('\Helper\Wpunit')->clear_loader_cache( 'wc_customer' ); + $this->assertQuerySuccessful( $response, $expected ); /** * Assertion Two * * Query should return requested data because user has proper capabilities. */ - $this->set_user( $this->shop_manager ); - $actual = graphql( array( 'query' => $query ) ); + $this->loginAsShopManager(); + $response = $this->graphql( compact( 'query' ) ); $expected = array( - 'data' => array( - 'customers' => array( - 'nodes' => $this->helper->print_nodes( $users ), - ), - ), + $this->expectedObject( 'customers.nodes.#.databaseId', $users[0] ), + $this->expectedObject( 'customers.nodes.#.databaseId', $users[1] ), + $this->expectedObject( 'customers.nodes.#.databaseId', $users[2] ), + $this->expectedObject( 'customers.nodes.#.databaseId', $users[3] ), ); - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); + $this->assertQuerySuccessful( $response, $expected ); /** * Assertion Three @@ -276,81 +295,41 @@ public function testCustomersQueryAndWhereArgs() { * Tests "search" where argument. */ $variables = array( 'search' => 'megaman8080' ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); + $response = $this->graphql( compact( 'query', 'variables' ) ); $expected = array( - 'data' => array( - 'customers' => array( - 'nodes' => $this->helper->print_nodes( - $users, - array( - 'filter' => function( $id ) { - $customer = new \WC_Customer( $id ); - return 'megaman8080' === $customer->get_username(); - } - ) - ), - ), - ), + $this->expectedObject( 'customers.nodes.0.databaseId', $users[0] ), ); - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); + $this->assertQuerySuccessful( $response, $expected ); /** * Assertion Four * * Tests "include" where argument. */ - $variables = array( 'include' => array( $user_id ) ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); + $variables = array( 'include' => array( $users[2]) ); + $response = $this->graphql( compact( 'query', 'variables' ) ); $expected = array( - 'data' => array( - 'customers' => array( - 'nodes' => $this->helper->print_nodes( - $users, - array( - 'filter' => function( $id ) use ( $user_id ) { - return absint( $id ) === $user_id; - } - ) - ), - ), - ), + $this->expectedObject( 'customers.nodes.0.databaseId', $users[2] ), ); - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); + $this->assertQuerySuccessful( $response, $expected ); /** * Assertion Five * * Tests "exclude" where argument. */ - $variables = array( 'exclude' => array( $user_id ) ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); + $variables = array( 'exclude' => array( $users[2] ) ); + $response = $this->graphql( compact( 'query', 'variables' ) ); $expected = array( - 'data' => array( - 'customers' => array( - 'nodes' => $this->helper->print_nodes( - $users, - array( - 'filter' => function( $id ) use( $user_id ) { - return absint( $id ) !== $user_id; - } - ) - ), - ), - ), + $this->expectedObject( 'customers.nodes.#.databaseId', $users[0] ), + $this->expectedObject( 'customers.nodes.#.databaseId', $users[1] ), + $this->expectedObject( 'customers.nodes.#.databaseId', $users[3] ), + $this->not()->expectedObject( 'customers.nodes.#.databaseId', $users[2] ), ); - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); + $this->assertQuerySuccessful( $response, $expected ); /** * Assertion Six @@ -358,144 +337,58 @@ public function testCustomersQueryAndWhereArgs() { * Tests "email" where argument. */ $variables = array( 'email' => 'gotcha@example.com' ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); + $response = $this->graphql( compact( 'query', 'variables' ) ); $expected = array( - 'data' => array( - 'customers' => array( - 'nodes' => $this->helper->print_nodes( - $users, - array( - 'filter' => function( $id ) { - $customer = new \WC_Customer( $id ); - return 'gotcha@example.com' === $customer->get_email(); - } - ) - ), - ), - ), + $this->expectedObject( 'customers.nodes.0.databaseId', $users[0] ), + $this->not()->expectedObject( 'customers.nodes.#.databaseId', $users[1] ), + $this->not()->expectedObject( 'customers.nodes.#.databaseId', $users[2] ), + $this->not()->expectedObject( 'customers.nodes.#.databaseId', $users[3] ), ); - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); + $this->assertQuerySuccessful( $response, $expected ); /** * Assertion Seven * - * Tests "role" where argument. - */ - $variables = array( 'role' => 'SHOP_MANAGER' ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); - $expected = array( - 'data' => array( - 'customers' => array( - 'nodes' => $this->helper->print_nodes( array ( $this->shop_manager ) ), - ), - ), - ); - - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); - - /** - * Assertion Eight - * - * Tests "roleIn" where argument. Should - */ - $variables = array( 'roleIn' => array( 'SHOP_MANAGER' ) ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); - $expected = array( - 'data' => array( - 'customers' => array( - 'nodes' => $this->helper->print_nodes( array ( $this->shop_manager ) ), - ), - ), - ); - - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); - - /** - * Assertion Nine - * - * Tests "roleNotIn" where argument. - */ - $variables = array( 'roleNotIn' => array( 'SHOP_MANAGER' ) ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); - $expected = array( - 'data' => array( - 'customers' => array( - 'nodes' => $this->helper->print_nodes( - get_users( - array( - 'role__not_in' => 'shop_manager', - 'fields' => 'ID', - ) - ), - array( - 'filter' => function( $id ) { - $customer = new \WC_Customer( $id ); - return 'shop_manager' !== $customer->get_role(); - } - ) - ), - ), - ), - ); - - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); - - /** - * Assertion Ten - * * Tests "orderby" and "order" where arguments. */ $variables = array( 'orderby' => 'USERNAME', 'order' => 'ASC' ); - $actual = graphql( array( 'query' => $query, 'variables' => $variables ) ); - $expected = array( - 'data' => array( - 'customers' => array( - 'nodes' => $this->helper->print_nodes( - $users, - array( - 'sorter' => function( $id_a, $id_b ) { - $data = new \WC_Customer( $id_a ); - $username_a = $data->get_username(); - $data = new \WC_Customer( $id_b ); - $username_b = $data->get_username(); - - return strnatcmp( $username_a, $username_b ); - } - ) - ), - ), - ), + $response = $this->graphql( compact( 'query', 'variables' ) ); + + $all_users = get_users( + array( + 'fields' => 'ID', + 'role' => 'customer', + 'orderby' => 'username', + 'order' => 'ASC', + ) ); - - // use --debug flag to view. - codecept_debug( $actual ); - - $this->assertEquals( $expected, $actual ); + $expected = array(); + foreach ( $all_users as $index => $user_id ) { + $expected[] = $this->expectedObject( + "customers.nodes.{$index}.databaseId", + absint( $user_id ) + ); + } + + $this->assertQuerySuccessful( $response, $expected ); } public function testCustomerToOrdersConnection() { - $this->order_1 = $this->order_helper->create( array( 'customer_id' => $this->customer ) ); - $this->order_2 = $this->order_helper->create( array( 'customer_id' => $this->new_customer ) ); + $new_customer_id = $this->factory->customer->create(); + $order_1 = $this->factory->order->createNew( + array( 'customer_id' => $this->customer ) + ); + $order_2 = $this->factory->order->createNew( + array( 'customer_id' => $new_customer_id ) + ); $query = ' query { customer { orders { nodes { - id + databaseId } } } @@ -507,20 +400,12 @@ public function testCustomerToOrdersConnection() { * * Query for authenticated customer's orders. */ - $this->set_user( $this->customer ); - $actual = graphql( array( 'query' => $query ) ); + $this->loginAsCustomer(); + $response = $this->graphql( compact( 'query' ) ); $expected = array( - 'data' => array( - 'customer' => array( - 'orders' => array( - 'nodes' => array( - array( 'id' => $this->order_helper->to_relay_id( $this->order_1 ) ), - ) - ) - ) - ) + $this->expectedObject( 'customer.orders.nodes.#.databaseId', $order_1 ), ); - $this->assertEquals( $expected, $actual ); + $this->assertQuerySuccessful( $response, $expected ); } } diff --git a/tests/wpunit/RefundQueriesTest.php b/tests/wpunit/RefundQueriesTest.php index b86fbae15..3666e0f76 100644 --- a/tests/wpunit/RefundQueriesTest.php +++ b/tests/wpunit/RefundQueriesTest.php @@ -12,7 +12,7 @@ public function expectedRefundData( $refund_id ) { $this->expectedObject( 'refund.title', $refund->get_post_title() ), $this->expectedObject( 'refund.reason', $refund->get_reason() ), $this->expectedObject( 'refund.amount', floatval( $refund->get_amount() ) ), - $this->expectedObject( 'refund.refundedBy.id', $this->toRelayId( 'user', $refund->get_refunded_by() ) ), + $this->expectedObject( 'refund.refundedBy.databaseId', $refund->get_refunded_by() ), $this->expectedObject( 'refund.date', (string) $refund->get_date_modified() ), ); } @@ -33,7 +33,7 @@ public function testRefundQuery() { reason amount refundedBy { - id + databaseId } date } diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index d7f096a86..48e2bfebe 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -5,7 +5,7 @@ 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '0300aab12e31e4bc64d4d80b392eb846dfa6b3ae', + 'reference' => '3c401054991aa24d8b1c07f90fb0dae030f36b94', 'name' => 'wp-graphql/wp-graphql-woocommerce', 'dev' => false, ), @@ -25,7 +25,7 @@ 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '0300aab12e31e4bc64d4d80b392eb846dfa6b3ae', + 'reference' => '3c401054991aa24d8b1c07f90fb0dae030f36b94', 'dev_requirement' => false, ), ),