Files

1228 lines
31 KiB
PHP
Raw Permalink Normal View History

2019-03-13 12:31:37 -04:00
<?php
2020-10-22 15:59:11 -04:00
class ProductQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
public function getExpectedProductData( $product_id ) {
$product = \wc_get_product( $product_id );
$is_shop_manager = false;
$user = wp_get_current_user();
if ( $user && in_array( 'shop_manager', (array) $user->roles, true ) ) {
$is_shop_manager = true;
}
2019-03-13 12:31:37 -04:00
return [
$this->expectedField( 'product.id', $this->toRelayId( 'post', $product_id ) ),
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.databaseId', $product->get_id() ),
$this->expectedField( 'product.name', $product->get_name() ),
$this->expectedField( 'product.slug', $product->get_slug() ),
$this->expectedField( 'product.date', $product->get_date_created()->__toString() ),
$this->expectedField( 'product.status', $product->get_status() ),
$this->expectedField( 'product.featured', $product->get_featured() ),
$this->expectedField(
'product.description',
$this->maybe(
[ $product->get_description(), apply_filters( 'the_content', $product->get_description() ) ],
static::IS_NULL
)
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.shortDescription',
$this->maybe(
[
$product->get_short_description(),
apply_filters(
'get_the_excerpt',
apply_filters( 'the_excerpt', $product->get_short_description() )
),
],
static::IS_NULL
)
),
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.sku', $product->get_sku() ),
$this->expectedField(
'product.price',
$this->maybe(
[ $product->get_price(), \wc_graphql_price( $product->get_price() ) ],
static::IS_NULL
)
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.regularPrice',
$this->maybe(
[ $product->get_regular_price(), \wc_graphql_price( $product->get_regular_price() ) ],
static::IS_NULL
)
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.salePrice',
$this->maybe(
[ $product->get_sale_price(), \wc_graphql_price( $product->get_sale_price() ) ],
static::IS_NULL
)
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.dateOnSaleFrom',
$this->maybe( $product->get_date_on_sale_from(), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.dateOnSaleTo',
$this->maybe( $product->get_date_on_sale_to(), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.taxStatus',
$this->maybe( strtoupper( $product->get_tax_status() ), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.taxClass',
$this->maybe( $product->get_tax_class(), 'STANDARD' )
),
$this->expectedField(
'product.manageStock',
! empty( $product->get_manage_stock() )
? \WPGraphQL\Type\WPEnumType::get_safe_name( $product->get_manage_stock() )
: static::IS_NULL
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.stockQuantity',
$this->maybe( $product->get_stock_quantity(), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.stockStatus',
$this->maybe(
$this->factory->product->getStockStatusEnum( $product->get_stock_status() ),
static::IS_NULL
)
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.backorders',
$this->maybe(
\WPGraphQL\Type\WPEnumType::get_safe_name( $product->get_backorders() ),
static::IS_NULL
)
),
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.soldIndividually', $product->get_sold_individually() ),
$this->expectedField(
'product.weight',
$this->maybe( $product->get_weight(), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.length',
$this->maybe( $product->get_length(), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.width',
$this->maybe( $product->get_width(), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.height',
$this->maybe( $product->get_height(), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.reviewsAllowed',
$this->maybe( $product->get_reviews_allowed(), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.purchaseNote',
$this->maybe( $product->get_purchase_note(), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.menuOrder', $product->get_menu_order() ),
$this->expectedField( 'product.virtual', $product->get_virtual() ),
$this->expectedField( 'product.downloadable', $product->get_downloadable(), static::IS_NULL ),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.downloadLimit',
$this->maybe( $product->get_download_limit(), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.downloadExpiry',
$this->maybe( $product->get_download_expiry(), static::IS_NULL )
),
$this->expectedField( 'product.averageRating', (float) $product->get_average_rating() ),
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.reviewCount', (int) $product->get_review_count() ),
$this->expectedField(
'product.backordersAllowed',
$this->maybe( $product->backorders_allowed(), static::IS_FALSY )
),
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.onSale', $product->is_on_sale() ),
$this->expectedField( 'product.purchasable', $product->is_purchasable() ),
$this->expectedField( 'product.shippingRequired', $product->needs_shipping() ),
$this->expectedField( 'product.shippingTaxable', $product->is_shipping_taxable() ),
$this->expectedField(
'product.link',
$this->maybe( get_post_permalink( $product_id ), static::IS_NULL )
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.totalSales',
$this->maybe(
[
$is_shop_manager && $product->get_total_sales(),
$product->get_total_sales(),
],
static::IS_FALSY
)
),
2021-07-05 13:51:52 -04:00
$this->expectedField(
'product.catalogVisibility',
$this->maybe(
[
$is_shop_manager && ! empty( $product->get_catalog_visibility() ),
strtoupper( $product->get_catalog_visibility() ),
],
static::IS_NULL
)
),
];
2019-03-21 21:43:24 -04:00
}
2019-03-13 12:31:37 -04:00
public function getExpectedProductDownloadData( $product_id ) {
$product = wc_get_product( $product_id );
$downloads = (array) $product->get_downloads();
if ( empty( $downloads ) ) {
return null;
}
2019-11-13 21:06:01 -05:00
$results = [];
foreach ( $downloads as $download ) {
$results[] = [
'name' => $download->get_name(),
'downloadId' => $download->get_id(),
'filePathType' => $download->get_type_of_file_path(),
'fileType' => $download->get_file_type(),
'fileExt' => $download->get_file_extension(),
'allowedFileType' => $download->is_allowed_filetype(),
'fileExists' => $download->file_exists(),
'file' => $download->get_file(),
];
}
return $results;
2019-03-21 21:43:24 -04:00
}
2019-03-13 12:31:37 -04:00
2019-03-21 21:43:24 -04:00
// tests
2019-10-17 21:39:38 -04:00
public function testSimpleProductQuery() {
$product_id = $this->factory->product->createSimple();
$product = wc_get_product( $product_id );
$query = '
query ( $id: ID!, $format: PostObjectFieldFormatEnum ) {
product(id: $id) {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
id
2020-09-16 16:32:14 -04:00
databaseId
2019-10-17 21:39:38 -04:00
name
slug
date
modified
status
featured
catalogVisibility
description(format: $format)
shortDescription(format: $format)
sku
price
regularPrice
salePrice
dateOnSaleFrom
dateOnSaleTo
totalSales
taxStatus
taxClass
manageStock
stockQuantity
stockStatus
backorders
soldIndividually
weight
length
width
height
reviewsAllowed
purchaseNote
menuOrder
virtual
downloadable
downloadLimit
downloadExpiry
averageRating
reviewCount
backordersAllowed
onSale
purchasable
shippingRequired
shippingTaxable
2019-11-04 22:49:03 -05:00
link
2019-10-17 21:39:38 -04:00
}
2019-03-21 21:43:24 -04:00
}
}
';
2020-06-01 21:53:24 -04:00
/**
* Assertion One
2020-06-01 21:53:24 -04:00
*
* Test querying product.
*/
$variables = [ 'id' => $this->toRelayId( 'post', $product_id ) ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = $this->getExpectedProductData( $product_id );
2019-03-17 23:50:15 -04:00
$this->assertQuerySuccessful( $response, $expected );
// Clear cache
$this->clearLoaderCache( 'wc_post' );
/**
* Assertion Two
2020-06-01 21:53:24 -04:00
*
* Test querying product with unformatted content (edit-product cap required).
*/
$this->loginAsShopManager();
$variables = [
'id' => $this->toRelayId( 'post', $product_id ),
'format' => 'RAW',
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.description', $product->get_description() ),
$this->expectedField( 'product.shortDescription', $product->get_short_description() ),
$this->expectedField( 'product.totalSales', $product->get_total_sales() ),
$this->expectedField( 'product.catalogVisibility', strtoupper( $product->get_catalog_visibility() ) ),
];
$this->assertQuerySuccessful( $response, $expected );
2019-03-21 21:43:24 -04:00
}
2019-03-14 23:55:34 -04:00
2019-10-15 22:43:01 -04:00
public function testProductTaxonomies() {
// Create product and properties.
$category_5 = $this->factory->product->createProductCategory( 'category-five' );
$category_6 = $this->factory->product->createProductCategory( 'category-six', $category_5 );
$tag_2 = $this->factory->product->createProductTag( 'tag-two' );
$attachment_id = $this->factory->attachment->create(
[
2019-10-15 22:48:04 -04:00
'post_mime_type' => 'image/gif',
'post_author' => $this->admin,
]
2019-10-15 22:48:04 -04:00
);
$product_id = $this->factory->product->createSimple(
[
2019-10-15 22:43:01 -04:00
'price' => 10,
'regular_price' => 10,
'category_ids' => [ $category_5 ],
'tag_ids' => [ $tag_2 ],
2019-10-15 22:48:04 -04:00
'image_id' => $attachment_id,
]
2019-10-15 22:43:01 -04:00
);
$query = '
query ( $id: ID!, $idType: ProductIdTypeEnum ) {
product( id: $id, idType: $idType ) {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
2019-10-15 22:48:04 -04:00
id
2019-10-17 21:39:38 -04:00
image {
id
}
2019-11-28 12:56:27 -05:00
productCategories {
2019-10-17 21:39:38 -04:00
nodes {
name
2020-08-06 16:25:50 -04:00
image { id }
display
menuOrder
2019-10-17 21:39:38 -04:00
children {
nodes {
name
}
2019-10-15 22:43:01 -04:00
}
}
}
2019-11-28 12:56:27 -05:00
productTags {
2019-10-17 21:39:38 -04:00
nodes {
name
}
2019-10-15 22:43:01 -04:00
}
}
}
}
';
/**
* Assertion One
2020-06-01 21:53:24 -04:00
*
2019-10-15 22:43:01 -04:00
* Test querying product with "productId" argument.
*/
$variables = [
'id' => $product_id,
'idType' => 'DATABASE_ID',
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedField( 'product.id', $this->toRelayId( 'post', $product_id ) ),
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.image.id', $this->toRelayId( 'post', $attachment_id ) ),
$this->expectedNode(
'product.productCategories.nodes',
[
2020-10-27 23:55:16 -04:00
'name' => 'category-five',
'image' => null,
'display' => 'DEFAULT',
'menuOrder' => 0,
'children' => [
'nodes' => [
[ 'name' => 'category-six' ],
],
],
]
2019-10-15 22:43:01 -04:00
),
$this->expectedNode( 'product.productTags.nodes', [ 'name' => 'tag-two' ] ),
];
2019-10-15 22:43:01 -04:00
$this->assertQuerySuccessful( $response, $expected );
2019-10-15 22:43:01 -04:00
}
2020-01-24 23:40:50 -05:00
public function testProductQueryAndIds() {
$product_id = $this->factory->product->createSimple();
$query = '
2020-01-24 23:40:50 -05:00
query ( $id: ID!, $idType: ProductIdTypeEnum ) {
product( id: $id, idType: $idType ) {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
id
}
2019-03-21 21:43:24 -04:00
}
}
';
2019-03-17 23:50:15 -04:00
// Define expected data for coming assertions.
$expected = [
$this->expectedField( 'product.id', $this->toRelayId( 'post', $product_id ) ),
];
/**
* Assertion One
2020-06-01 21:53:24 -04:00
*
* Test querying product with 'DATABASE_ID' set as the "idType".
*/
$variables = [
'id' => $product_id,
2020-01-24 23:40:50 -05:00
'idType' => 'DATABASE_ID',
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$this->assertQuerySuccessful( $response, $expected );
/**
* Assertion Two
2020-06-01 21:53:24 -04:00
*
* Test querying product with "ID" set as the "idType".
*/
$variables = [
'id' => $this->toRelayId( 'post', $product_id ),
2020-01-24 23:40:50 -05:00
'idType' => 'ID',
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$this->assertQuerySuccessful( $response, $expected );
/**
* Assertion Three
2020-06-01 21:53:24 -04:00
*
* Test querying product with "SLUG" set as the "idType".
*/
$variables = [
'id' => get_post_field( 'post_name', $product_id ),
2020-01-24 23:40:50 -05:00
'idType' => 'SLUG',
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$this->assertQuerySuccessful( $response, $expected );
/**
* Assertion Four
2020-06-01 21:53:24 -04:00
*
* Test querying product with "SKU" set as the "idType".
*/
$variables = [
'id' => get_post_meta( $product_id, '_sku', true ),
2020-01-24 23:40:50 -05:00
'idType' => 'SKU',
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$this->assertQuerySuccessful( $response, $expected );
}
public function testProductToTermConnection() {
$test_category = $this->factory->product->createProductCategory( 'test-product-category-1' );
$test_tag = $this->factory->product->createProductTag( 'test-product-tag-1' );
$product_id = $this->factory->product->createSimple(
[
'tag_ids' => [ $test_tag ],
'category_ids' => [ $test_category ],
]
);
$relay_id = $this->toRelayId( 'post', $product_id );
$query = '
2019-10-17 21:39:38 -04:00
query ($id: ID!) {
product(id: $id) {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
id
2019-11-28 12:56:27 -05:00
productTags {
2019-10-17 21:39:38 -04:00
nodes {
name
}
}
2019-11-28 12:56:27 -05:00
productCategories {
2019-10-17 21:39:38 -04:00
nodes {
name
}
}
}
}
}
';
$variables = [ 'id' => $relay_id ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.id', $relay_id ),
$this->expectedNode(
'product.productTags.nodes',
[ 'name' => 'test-product-tag-1' ],
0
),
$this->expectedNode(
'product.productCategories.nodes',
[ 'name' => 'test-product-category-1' ],
0
),
];
$this->assertQuerySuccessful( $response, $expected );
}
public function testTermToProductConnection() {
$test_tag = $this->factory->product->createProductTag( 'test-product-tag-2' );
$image_id = $this->factory->post->create(
[
'post_author' => $this->shop_manager,
'post_status' => 'publish',
'post_title' => 'Product Image',
'post_type' => 'attachment',
]
);
$test_category = $this->factory->product->createProductCategory( 'test-product-category-2' );
update_term_meta( $test_category, 'thumbnail_id', $image_id );
$product_id = $this->factory->product->createSimple(
[
'tag_ids' => [ $test_tag ],
'category_ids' => [ $test_category ],
'price' => 10,
'regular_price' => 10,
]
);
$expensive_product_id = $this->factory->product->createSimple(
[
'tag_ids' => [ $test_tag ],
'category_ids' => [ $test_category ],
'price' => 100,
'regular_price' => 100,
]
);
$query = '
query($orderby: [ProductsOrderbyInput], $orderby2: [ProductsOrderbyInput]) {
2019-06-05 14:48:32 -04:00
productTags( where: { hideEmpty: true } ) {
nodes {
name
products(where: {orderby: $orderby}) {
nodes {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
id
price
2019-10-17 21:39:38 -04:00
}
}
}
}
}
2019-06-05 14:48:32 -04:00
productCategories( where: { hideEmpty: true } ) {
nodes {
name
2019-07-09 22:40:54 -04:00
image {
id
}
products(where: {orderby: $orderby2}) {
nodes {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
id
price
2019-10-17 21:39:38 -04:00
}
}
}
}
}
}
';
$variables = [
'orderby' => [
[
'field' => 'PRICE',
'order' => 'ASC',
],
],
'orderby2' => [
[
'field' => 'PRICE',
'order' => 'DESC',
],
],
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedNode(
'productTags.nodes',
[
$this->expectedField( 'name', 'test-product-tag-2' ),
$this->expectedField( 'products.nodes.0.id', $this->toRelayId( 'post', $product_id ) ),
$this->expectedField( 'products.nodes.1.id', $this->toRelayId( 'post', $expensive_product_id ) ),
],
0
),
$this->expectedNode(
'productCategories.nodes',
[
$this->expectedField( 'name', 'test-product-category-2' ),
$this->expectedField( 'image.id', $this->toRelayId( 'post', $image_id ) ),
$this->expectedField( 'products.nodes.1.id', $this->toRelayId( 'post', $product_id ) ),
$this->expectedField( 'products.nodes.0.id', $this->toRelayId( 'post', $expensive_product_id ) ),
],
0
),
];
$this->assertQuerySuccessful( $response, $expected );
}
2019-06-05 14:48:32 -04:00
public function testProductToMediaItemConnections() {
$image_id = $this->factory->post->create(
[
'post_author' => $this->shop_manager,
'post_status' => 'publish',
'post_title' => 'Product Image',
'post_type' => 'attachment',
]
);
$product_id = $this->factory->product->createSimple(
[
'image_id' => $image_id,
'gallery_image_ids' => [ $image_id ],
]
);
$product_relay_id = $this->toRelayId( 'post', $product_id );
$image_relay_id = $this->toRelayId( 'post', $image_id );
$query = '
2019-10-17 21:39:38 -04:00
query ( $id: ID! ) {
2019-06-05 14:48:32 -04:00
product( id: $id ) {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
2019-06-05 14:48:32 -04:00
id
2019-10-17 21:39:38 -04:00
image {
2019-06-05 14:48:32 -04:00
id
}
2019-10-17 21:39:38 -04:00
galleryImages {
nodes {
id
}
}
2019-06-05 14:48:32 -04:00
}
}
}
';
$variables = [ 'id' => $product_relay_id ];
$response = graphql( compact( 'query', 'variables' ) );
$expected = [
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.id', $product_relay_id ),
$this->expectedField( 'product.image.id', $image_relay_id ),
$this->expectedNode( 'product.galleryImages.nodes', [ 'id' => $image_relay_id ] ),
];
2019-06-05 14:48:32 -04:00
$this->assertQuerySuccessful( $response, $expected );
2019-06-05 14:48:32 -04:00
}
public function testProductDownloads() {
$product_id = $this->factory->product->createSimple(
[
'downloadable' => true,
'downloads' => [ $this->factory->product->createDownload() ],
]
);
$relay_id = $this->toRelayId( 'post', $product_id );
$query = '
2019-10-17 21:39:38 -04:00
query ( $id: ID! ) {
product( id: $id ) {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
id
downloads {
name
downloadId
filePathType
fileType
fileExt
allowedFileType
fileExists
file
}
}
}
}
';
$variables = [ 'id' => $relay_id ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.id', $relay_id ),
$this->expectedField( 'product.downloads', $this->getExpectedProductDownloadData( $product_id ) ),
];
$this->assertQuerySuccessful( $response, $expected );
}
public function testExternalProductQuery() {
$product_id = $this->factory->product->createExternal(
[
'product_url' => 'http://woographql.com',
'button_text' => 'Buy a external product',
]
);
$relay_id = $this->toRelayId( 'post', $product_id );
$query = '
2019-10-17 21:39:38 -04:00
query ( $id: ID! ) {
product(id: $id) {
2019-10-17 21:39:38 -04:00
... on ExternalProduct {
id
buttonText
externalUrl
}
}
}
';
$variables = [ 'id' => $relay_id ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.id', $relay_id ),
$this->expectedField( 'product.buttonText', 'Buy a external product' ),
$this->expectedField( 'product.externalUrl', 'http://woographql.com' ),
];
$this->assertQuerySuccessful( $response, $expected );
}
public function testGroupProductConnections() {
$product_id = $this->factory->product->createGrouped(
[
'name' => 'Test Group',
'children' => [],
]
);
$grouped_product_ids = [
$this->factory->product->createSimple( [ 'regular_price' => '1.00' ] ),
$this->factory->product->createSimple( [ 'regular_price' => '5.00' ] ),
$this->factory->product->createSimple( [ 'regular_price' => '10.00' ] ),
];
$product = \wc_get_product( $product_id );
$this->factory->product->update_object(
$product,
[ 'children' => $grouped_product_ids ]
);
$relay_id = $this->toRelayId( 'post', $product_id );
$query = '
2019-10-17 21:39:38 -04:00
query ( $id: ID! ) {
product(id: $id) {
id
2019-10-17 21:39:38 -04:00
... on GroupProduct {
addToCartText
addToCartDescription
products {
nodes { id }
}
}
}
}
';
$variables = [ 'id' => $relay_id ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.id', $relay_id ),
$this->expectedField( 'product.addToCartText', 'View products' ),
$this->expectedField(
'product.addToCartDescription',
/* translators: %s: Group name */
sprintf( __( 'View products in the &ldquo;%s&rdquo; group', 'graphql-for-ecommerce' ), 'Test Group' )
),
];
foreach ( $product->get_children() as $grouped_product_id ) {
$expected[] = $this->expectedNode(
'product.products.nodes',
[ 'id' => $this->toRelayId( 'post', $grouped_product_id ) ]
);
}
$this->assertQuerySuccessful( $response, $expected );
2021-02-26 09:29:19 -05:00
$query = '
query ( $id: ID! ) {
product( id: $id ) {
... on GroupProduct {
price
}
}
}
';
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [ $this->expectedField( 'product.price', '$1.00 - $10.00' ) ];
2021-02-26 09:29:19 -05:00
$this->assertQuerySuccessful( $response, $expected );
}
public function testRelatedProductConnections() {
$products = $this->factory->product->createRelated();
$query = '
2019-10-17 21:39:38 -04:00
query ($id: ID!) {
product(id: $id) {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
related {
2019-10-17 21:39:38 -04:00
nodes {
... on SimpleProduct {
id
}
}
}
crossSell{
2019-10-17 21:39:38 -04:00
nodes {
... on SimpleProduct {
id
}
}
}
2019-10-17 21:39:38 -04:00
upsell {
nodes {
... on SimpleProduct {
id
}
}
}
}
}
}
';
$variables = [ 'id' => $this->toRelayId( 'post', $products['product'] ) ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [];
foreach ( $products['related'] + $products['cross_sell'] + $products['upsell'] as $product_id ) {
$expected[] = $this->expectedNode(
'product.related.nodes',
[ 'id' => $this->toRelayId( 'post', $product_id ) ]
);
}
foreach ( $products['cross_sell'] as $product_id ) {
$expected[] = $this->expectedNode(
'product.crossSell.nodes',
[ 'id' => $this->toRelayId( 'post', $product_id ) ]
);
}
foreach ( $products['upsell'] as $product_id ) {
$expected[] = $this->expectedNode(
'product.upsell.nodes',
[ 'id' => $this->toRelayId( 'post', $product_id ) ]
);
}
$this->assertQuerySuccessful( $response, $expected );
}
2019-12-18 15:11:59 -05:00
public function testProductToReviewConnections() {
$product_id = $this->factory->product->createSimple();
$reviews = [
$this->factory->product->createReview( $product_id ),
$this->factory->product->createReview( $product_id ),
$this->factory->product->createReview( $product_id ),
$this->factory->product->createReview( $product_id ),
$this->factory->product->createReview( $product_id ),
];
$relay_id = $this->toRelayId( 'post', $product_id );
$product = \wc_get_product( $product_id );
2019-12-18 15:11:59 -05:00
$query = '
query ($id: ID!) {
product(id: $id) {
id
2020-10-13 15:01:44 -04:00
reviews(last: 5) {
2019-12-18 15:11:59 -05:00
averageRating
edges {
rating
node {
id
}
}
}
}
}
';
$variables = [ 'id' => $relay_id ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
2021-07-05 13:51:52 -04:00
$this->expectedField( 'product.id', $relay_id ),
$this->expectedField( 'product.reviews.averageRating', floatval( $product->get_average_rating() ) ),
];
2019-12-18 15:11:59 -05:00
foreach ( $reviews as $review_id ) {
$expected[] = $this->expectedEdge(
'product.reviews.edges',
[
'rating' => floatval( get_comment_meta( $review_id, 'rating', true ) ),
'node' => [ 'id' => $this->toRelayId( 'comment', $review_id ) ],
]
);
}
2019-12-18 15:11:59 -05:00
$this->assertQuerySuccessful( $response, $expected );
2019-12-18 15:11:59 -05:00
}
2020-07-13 19:17:28 -04:00
public function testProductGalleryImagesConnection() {
$image_id = $this->factory->post->create(
[
2020-07-13 19:17:28 -04:00
'post_type' => 'attachment',
'post_content' => 'Lorem ipsum dolor...',
]
2020-07-13 19:17:28 -04:00
);
2020-10-27 23:55:16 -04:00
$product_id = $this->factory->product->createSimple(
[ 'gallery_image_ids' => [ $image_id ] ]
2020-07-13 19:17:28 -04:00
);
$query = '
query( $id: ID! ) {
product( id: $id ) {
galleryImages {
nodes {
id
}
}
}
}
';
$variables = [ 'id' => $this->toRelayId( 'post', $product_id ) ];
$response = $this->graphql( compact( 'query', 'variables' ) );
2020-10-27 23:55:16 -04:00
$this->assertQuerySuccessful(
$response,
[
2020-10-27 23:55:16 -04:00
$this->expectedNode(
'product.galleryImages.nodes',
[ 'id' => $this->toRelayId( 'post', $image_id ) ]
),
]
2020-07-13 19:17:28 -04:00
);
}
// tests
public function testProductQueryWithInterfaces() {
$product_id = $this->factory->product->createSimple();
$product = wc_get_product( $product_id );
$query = '
query ( $id: ID!, $format: PostObjectFieldFormatEnum ) {
product(id: $id) {
id
databaseId
name
slug
date
modified
status
featured
catalogVisibility
description(format: $format)
shortDescription(format: $format)
sku
dateOnSaleFrom
dateOnSaleTo
totalSales
averageRating
reviewCount
onSale
purchasable
link
reviewsAllowed
purchaseNote
menuOrder
2025-05-01 14:46:55 -04:00
virtual
... on ProductWithPricing {
price
regularPrice
salePrice
taxStatus
taxClass
}
... on InventoriedProduct {
manageStock
stockQuantity
backorders
soldIndividually
backordersAllowed
stockStatus
}
... on ProductWithDimensions {
weight
length
width
height
shippingClassId
shippingRequired
shippingTaxable
}
... on DownloadableProduct {
downloadExpiry
downloadable
downloadLimit
}
}
}
';
/**
* Assertion One
*
* Test querying product.
*/
$variables = [ 'id' => $this->toRelayId( 'post', $product_id ) ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = $this->getExpectedProductData( $product_id );
$this->assertQuerySuccessful( $response, $expected );
// Clear cache
$this->clearLoaderCache( 'wc_post' );
/**
* Assertion Two
*
* Test querying product with unformatted content (edit-product cap required).
*/
$this->loginAsShopManager();
$variables = [
'id' => $this->toRelayId( 'post', $product_id ),
'format' => 'RAW',
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedField( 'product.description', $product->get_description() ),
$this->expectedField( 'product.shortDescription', $product->get_short_description() ),
$this->expectedField( 'product.totalSales', $product->get_total_sales() ),
$this->expectedField( 'product.catalogVisibility', strtoupper( $product->get_catalog_visibility() ) ),
];
$this->assertQuerySuccessful( $response, $expected );
}
public function testProductsQueryWithAttributesFilter() {
// Create product attributes.
$kind_attribute = $this->factory->product->createAttribute( 'kind', [ 'special', 'normal' ], 'Product type' );
$normal_term_id = get_term_by( 'slug', 'normal', 'pa_kind' )->term_id;
$special_term_id = get_term_by( 'slug', 'special', 'pa_kind' )->term_id;
// Create attribute objects.
$kind_attribute_normal_only = $this->factory->product->createAttributeObject(
$kind_attribute['attribute_id'],
$kind_attribute['attribute_taxonomy'],
[ $normal_term_id ]
);
$kind_attribute_special_only = $this->factory->product->createAttributeObject(
$kind_attribute['attribute_id'],
$kind_attribute['attribute_taxonomy'],
[ $special_term_id ]
);
$kind_attribute_both = $this->factory->product->createAttributeObject(
$kind_attribute['attribute_id'],
$kind_attribute['attribute_taxonomy'],
[ $normal_term_id, $special_term_id ]
);
// Create products.
$normal_product_id = $this->factory->product->createSimple(
[
'attributes' => [ $kind_attribute_normal_only ],
'default_attributes' => [ 'pa_kind' => 'normal' ],
]
);
$special_product_id = $this->factory->product->createSimple(
[
'attributes' => [ $kind_attribute_special_only ],
'default_attributes' => [ 'pa_kind' => 'special' ],
]
);
$both_product_id = $this->factory->product->createSimple(
[
'attributes' => [ $kind_attribute_both ],
]
);
// Create query.
$query = '
query( $where: RootQueryToProductConnectionWhereArgs ) {
products( where: $where ) {
nodes {
... on SimpleProduct {
id
}
}
}
}
';
$variables = [
'where' => [
'attributes' => [
'queries' => [
[
'taxonomy' => 'PA_KIND',
'terms' => [ 'normal' ],
],
],
],
],
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedNode(
'products.nodes',
[ 'id' => $this->toRelayId( 'post', $normal_product_id ) ]
),
];
$this->assertQuerySuccessful( $response, $expected );
$variables = [
'where' => [
'attributes' => [
'queries' => [
[
'taxonomy' => 'PA_KIND',
'terms' => [ 'special' ],
],
],
],
],
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedNode(
'products.nodes',
[ 'id' => $this->toRelayId( 'post', $special_product_id ) ]
),
];
$this->assertQuerySuccessful( $response, $expected );
$variables = [
'where' => [
'attributes' => [
'queries' => [
[
'taxonomy' => 'PA_KIND',
'terms' => [ 'normal', 'special' ],
],
],
],
],
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedNode(
'products.nodes',
[ 'id' => $this->toRelayId( 'post', $both_product_id ) ]
),
];
$this->assertQuerySuccessful( $response, $expected );
$variables = [
'where' => [
'attributes' => [
'queries' => [
[
'taxonomy' => 'PA_KIND',
'terms' => [ 'normal', 'special' ],
'operator' => 'NOT_IN',
],
],
],
],
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedField(
'products.nodes',
static::IS_FALSY
),
];
$this->assertQuerySuccessful( $response, $expected );
$variables = [
'where' => [
'attributes' => [
'queries' => [
[
'taxonomy' => 'PA_KIND',
'terms' => [ 'normal' ],
'operator' => 'NOT_IN',
],
]
],
],
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedNode(
'products.nodes',
[ 'id' => $this->toRelayId( 'post', $special_product_id ) ]
),
];
$this->assertQuerySuccessful( $response, $expected );
$variables = [
'where' => [
'attributes' => [
'queries' => [
[
'taxonomy' => 'PA_KIND',
'terms' => [ 'normal' ],
],
[
'taxonomy' => 'PA_KIND',
'terms' => [ 'special' ],
],
],
'relation' => 'AND',
],
],
];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedNode(
'products.nodes',
[ 'id' => $this->toRelayId( 'post', $both_product_id ) ]
),
];
$this->assertQuerySuccessful( $response, $expected );
}
2019-08-26 15:13:51 -04:00
}