Files

457 lines
13 KiB
PHP
Raw Permalink Normal View History

2019-03-14 23:55:34 -04:00
<?php
2021-05-19 19:45:02 -04:00
class CouponQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
public function expectedCouponData( $coupon_id ) {
$coupon = new \WC_Coupon( $coupon_id );
$expected = [
2021-07-05 13:51:52 -04:00
$this->expectedField( 'coupon.id', $this->toRelayId( 'shop_coupon', $coupon_id ) ),
$this->expectedField( 'coupon.databaseId', $coupon->get_id() ),
$this->expectedField( 'coupon.code', $coupon->get_code() ),
$this->expectedField( 'coupon.amount', floatval( $coupon->get_amount() ) ),
$this->expectedField( 'coupon.date', $coupon->get_date_created()->__toString() ),
$this->expectedField( 'coupon.modified', $coupon->get_date_modified()->__toString() ),
$this->expectedField( 'coupon.discountType', strtoupper( $coupon->get_discount_type() ) ),
$this->expectedField( 'coupon.description', $coupon->get_description() ),
$this->expectedField( 'coupon.dateExpiry', $this->maybe( $coupon->get_date_expires(), static::IS_NULL ) ),
2021-07-05 13:51:52 -04:00
$this->expectedField( 'coupon.usageCount', $coupon->get_usage_count() ),
$this->expectedField( 'coupon.individualUse', $coupon->get_individual_use() ),
$this->expectedField( 'coupon.usageLimit', $this->maybe( $coupon->get_usage_limit(), static::IS_NULL ) ),
$this->expectedField( 'coupon.usageLimitPerUser', $this->maybe( $coupon->get_usage_limit_per_user(), static::IS_NULL ) ),
$this->expectedField( 'coupon.limitUsageToXItems', $this->maybe( $coupon->get_limit_usage_to_x_items(), static::IS_NULL ) ),
2021-07-05 13:51:52 -04:00
$this->expectedField( 'coupon.freeShipping', $coupon->get_free_shipping() ),
$this->expectedField( 'coupon.excludeSaleItems', $coupon->get_exclude_sale_items() ),
$this->expectedField( 'coupon.minimumAmount', $this->maybe( $coupon->get_minimum_amount(), static::IS_NULL ) ),
$this->expectedField( 'coupon.maximumAmount', $this->maybe( $coupon->get_maximum_amount(), static::IS_NULL ) ),
$this->expectedField( 'coupon.emailRestrictions', $this->maybe( $coupon->get_email_restrictions(), static::IS_NULL ) ),
];
2019-03-14 23:55:34 -04:00
foreach ( $coupon->get_product_ids() as $product_id ) {
$expected[] = $this->expectedNode( 'coupon.products.nodes', [ 'databaseId' => $product_id ] );
2021-05-19 19:45:02 -04:00
}
foreach ( $coupon->get_excluded_product_ids() as $product_id ) {
$expected[] = $this->expectedNode( 'coupon.excludedProducts.nodes', [ 'databaseId' => $product_id ] );
2021-05-19 19:45:02 -04:00
}
foreach ( $coupon->get_product_categories() as $category_id ) {
$expected[] = $this->expectedNode( 'coupon.productCategories.nodes', [ 'productCategoryId' => $category_id ] );
2021-05-19 19:45:02 -04:00
}
foreach ( $coupon->get_excluded_product_categories() as $category_id ) {
$expected[] = $this->expectedNode( 'coupon.excludedProductCategories.nodes', [ 'productCategoryId' => $category_id ] );
2021-05-19 19:45:02 -04:00
}
foreach ( $coupon->get_used_by() as $customer_id ) {
$expected[] = $this->expectedNode( 'coupon.usedBy.nodes', [ 'databaseId' => $customer_id ] );
2021-05-19 19:45:02 -04:00
}
return $expected;
2019-03-21 21:43:24 -04:00
}
2019-03-14 23:55:34 -04:00
2019-03-21 21:43:24 -04:00
// tests
public function testCouponQuery() {
2021-05-19 19:45:02 -04:00
$coupon_id = $this->factory->coupon->create(
[
'code' => '10off',
'amount' => 10,
'discount_type' => 'percent',
'product_ids' => [ $this->factory->product->createSimple() ],
'excluded_product_ids' => [ $this->factory->product->createSimple() ],
]
2021-05-19 19:45:02 -04:00
);
2019-10-17 21:39:38 -04:00
$query = '
query ($id: ID!){
coupon(id: $id) {
2019-03-31 22:48:57 -04:00
id
2020-09-16 16:32:14 -04:00
databaseId
2019-03-21 21:43:24 -04:00
code
amount
date
modified
discountType
description
dateExpiry
usageCount
individualUse
usageLimit
usageLimitPerUser
limitUsageToXItems
freeShipping
excludeSaleItems
minimumAmount
maximumAmount
emailRestrictions
products {
nodes {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
2020-09-16 16:32:14 -04:00
databaseId
2019-10-17 21:39:38 -04:00
}
2019-03-21 21:43:24 -04:00
}
}
excludedProducts {
nodes {
2019-10-17 21:39:38 -04:00
... on SimpleProduct {
2020-09-16 16:32:14 -04:00
databaseId
2019-10-17 21:39:38 -04:00
}
2019-03-21 21:43:24 -04:00
}
}
productCategories {
nodes {
productCategoryId
}
}
excludedProductCategories {
nodes {
productCategoryId
}
}
usedBy {
nodes {
2020-09-16 16:32:14 -04:00
databaseId
2019-03-21 21:43:24 -04:00
}
}
}
}
';
2019-03-15 23:33:01 -04:00
2019-03-21 21:43:24 -04:00
/**
2019-04-05 14:46:59 -04:00
* Assertion One
2023-04-18 23:43:39 -04:00
*
* Confirm customer's can't query coupons by ID.
2019-03-21 21:43:24 -04:00
*/
2021-05-19 19:45:02 -04:00
$this->loginAsCustomer();
$variables = [ 'id' => $this->toRelayId( 'shop_coupon', $coupon_id ) ];
2021-05-19 19:45:02 -04:00
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [ $this->expectedField( 'coupon', static::IS_NULL ) ];
2019-04-05 14:46:59 -04:00
2021-05-19 19:45:02 -04:00
$this->assertQuerySuccessful( $response, $expected );
2023-04-18 23:43:39 -04:00
/**
* Assertion Two
*
* Confirm shop managers can query coupons by ID.
*/
$this->loginAsShopManager();
$response = $this->graphql( compact( 'query', 'variables' ) );
$this->assertQuerySuccessful( $response, $this->expectedCouponData( $coupon_id ) );
2019-03-21 21:43:24 -04:00
}
2019-03-14 23:55:34 -04:00
2020-01-24 23:40:50 -05:00
public function testCouponQueryAndIds() {
2021-05-19 19:45:02 -04:00
$coupon_id = $this->factory->coupon->create();
$coupon = new \WC_Coupon( $coupon_id );
$relay_id = $this->toRelayId( 'shop_coupon', $coupon_id );
2019-03-21 21:43:24 -04:00
$query = '
2020-01-24 23:40:50 -05:00
query ($id: ID!, $idType: CouponIdTypeEnum) {
coupon(id: $id, idType: $idType) {
2019-04-05 14:46:59 -04:00
id
2019-03-21 21:43:24 -04:00
}
}
';
2019-03-15 23:33:01 -04:00
2019-03-21 21:43:24 -04:00
/**
2019-04-05 14:46:59 -04:00
* Assertion One
2020-09-16 16:32:14 -04:00
*
2020-01-24 23:40:50 -05:00
* Testing "ID" ID type.
2019-03-21 21:43:24 -04:00
*/
2023-04-18 23:43:39 -04:00
$this->loginAsShopManager();
$variables = [
2021-05-19 19:45:02 -04:00
'id' => $relay_id,
2020-01-24 23:40:50 -05:00
'idType' => 'ID',
];
2021-05-19 19:45:02 -04:00
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [ $this->expectedField( 'coupon.id', $relay_id ) ];
2021-05-19 19:45:02 -04:00
$this->assertQuerySuccessful( $response, $expected );
/**
* Assertion Two
2020-09-16 16:32:14 -04:00
*
2020-01-24 23:40:50 -05:00
* Testing "DATABASE_ID" ID type
*/
$variables = [
2021-05-19 19:45:02 -04:00
'id' => $coupon_id,
2020-01-24 23:40:50 -05:00
'idType' => 'DATABASE_ID',
];
2021-05-19 19:45:02 -04:00
$response = $this->graphql( compact( 'query', 'variables' ) );
2021-05-19 19:45:02 -04:00
$this->assertQuerySuccessful( $response, $expected );
/**
* Assertion Three
2020-09-16 16:32:14 -04:00
*
2020-01-24 23:40:50 -05:00
* Testing "CODE" ID type.
*/
$variables = [
2020-01-24 23:40:50 -05:00
'id' => $coupon->get_code(),
'idType' => 'CODE',
];
2021-05-19 19:45:02 -04:00
$response = $this->graphql( compact( 'query', 'variables' ) );
2019-03-15 23:33:01 -04:00
2021-05-19 19:45:02 -04:00
$this->assertQuerySuccessful( $response, $expected );
2019-03-21 21:43:24 -04:00
}
2019-03-14 23:55:34 -04:00
public function testCouponsQueryAndWhereArgs() {
$coupons = [
2021-05-19 19:45:02 -04:00
$this->factory->coupon->create(),
$this->factory->coupon->create(
[
2019-04-24 00:06:46 -04:00
'code' => '20off',
'amount' => 20,
'discount_type' => 'percent',
]
2019-04-17 14:18:35 -04:00
),
2021-05-19 19:45:02 -04:00
$this->factory->coupon->create(
[
2021-05-19 19:45:02 -04:00
'code' => 'testcode',
2019-04-24 00:06:46 -04:00
'amount' => 30,
'discount_type' => 'percent',
]
2019-04-17 14:18:35 -04:00
),
];
2019-03-21 21:43:24 -04:00
$query = '
2019-10-17 21:39:38 -04:00
query ($code: String, $include: [Int], $exclude: [Int]) {
coupons(where: { code: $code, include: $include, exclude: $exclude }) {
2019-03-21 21:43:24 -04:00
nodes {
2019-04-05 14:46:59 -04:00
id
2019-03-21 21:43:24 -04:00
}
}
}
';
2019-03-15 23:33:01 -04:00
2021-06-03 21:37:09 -04:00
/**
* Assertion One
*
* Should return null due to lack of required capabilities
*/
2021-05-19 19:45:02 -04:00
$this->loginAsCustomer();
$response = $this->graphql( compact( 'query' ) );
$expected = [
$this->expectedField( 'coupons.nodes', static::IS_FALSY ),
];
2019-04-05 14:46:59 -04:00
2021-06-04 00:05:24 -04:00
$this->assertQuerySuccessful( $response, $expected );
2019-04-05 14:46:59 -04:00
2021-06-03 21:37:09 -04:00
$this->clearLoaderCache( 'wc_post' );
2019-03-14 23:55:34 -04:00
2021-06-03 21:37:09 -04:00
/**
* Assertion Two
*
* Should return data because user has required capabilities
*/
2021-05-19 19:45:02 -04:00
$this->loginAsShopManager();
$response = $this->graphql( compact( 'query' ) );
$expected = [
$this->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['0'] ) ] ),
$this->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['1'] ) ] ),
$this->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['2'] ) ] ),
];
2019-03-15 23:33:01 -04:00
2021-05-19 19:45:02 -04:00
$this->assertQuerySuccessful( $response, $expected );
2021-06-03 21:37:09 -04:00
$this->clearLoaderCache( 'wc_post' );
/**
* Assertion Three
2020-09-16 16:32:14 -04:00
*
2019-04-24 00:06:46 -04:00
* Tests 'code' where argument
*/
$variables = [ 'code' => 'testcode' ];
2021-05-19 19:45:02 -04:00
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['2'] ) ] ),
$this->not()->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['0'] ) ] ),
$this->not()->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['1'] ) ] ),
];
2019-04-24 00:06:46 -04:00
2021-05-19 19:45:02 -04:00
$this->assertQuerySuccessful( $response, $expected );
2019-04-24 00:06:46 -04:00
2021-06-03 21:37:09 -04:00
$this->clearLoaderCache( 'wc_post' );
2019-04-24 00:06:46 -04:00
/**
* Assertion Four
2020-09-16 16:32:14 -04:00
*
2019-04-24 00:06:46 -04:00
* Tests 'include' where argument
*/
$variables = [ 'include' => $coupons[0] ];
2021-05-19 19:45:02 -04:00
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['0'] ) ] ),
$this->not()->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['1'] ) ] ),
$this->not()->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['2'] ) ] ),
];
2019-04-24 00:06:46 -04:00
2021-05-19 19:45:02 -04:00
$this->assertQuerySuccessful( $response, $expected );
2019-04-24 00:06:46 -04:00
/**
* Assertion Five
2020-09-16 16:32:14 -04:00
*
2019-04-24 00:06:46 -04:00
* Tests 'exclude' where argument
*/
$variables = [ 'exclude' => $coupons[0] ];
2021-05-19 19:45:02 -04:00
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->not()->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['0'] ) ] ),
$this->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['1'] ) ] ),
$this->expectedNode( 'coupons.nodes', [ 'id' => $this->toRelayId( 'shop_coupon', $coupons['2'] ) ] ),
2021-05-19 19:45:02 -04:00
];
2019-03-14 23:55:34 -04:00
2021-05-19 19:45:02 -04:00
$this->assertQuerySuccessful( $response, $expected );
2019-03-21 21:43:24 -04:00
}
/**
* Test coupon productCategories and excludedProductCategories connections.
*/
public function testCouponProductCategoryConnections() {
$this->loginAsShopManager();
// Create a WP category first to force term_id/term_taxonomy_id mismatch
// when the product_cat with the same name is created.
global $wpdb;
$wpdb->insert(
$wpdb->terms,
[
'name' => 'cat-a',
'slug' => 'cat-a',
'term_group' => 0,
]
);
$shared_term_id = (int) $wpdb->insert_id;
// Add term_taxonomy entry for 'category' (consumes a term_taxonomy_id).
$wpdb->insert(
$wpdb->term_taxonomy,
[
'term_id' => $shared_term_id,
'taxonomy' => 'category',
'description' => '',
'parent' => 0,
'count' => 0,
]
);
// Add term_taxonomy entry for 'product_cat' (different term_taxonomy_id, same term_id).
$wpdb->insert(
$wpdb->term_taxonomy,
[
'term_id' => $shared_term_id,
'taxonomy' => 'product_cat',
'description' => '',
'parent' => 0,
'count' => 0,
]
);
$cat_a_tt_id = (int) $wpdb->insert_id;
clean_term_cache( $shared_term_id, 'product_cat' );
clean_term_cache( $shared_term_id, 'category' );
// cat-a now has term_id != term_taxonomy_id.
$cat_a = $shared_term_id;
// Create normal product categories for the rest.
$cat_b = $this->factory->product->createProductCategory( 'cat-b' );
$cat_c = $this->factory->product->createProductCategory( 'cat-c' );
// Create coupon with product categories and excluded categories.
$coupon_id = $this->factory->coupon->create(
[
'code' => 'catcoupon',
'amount' => 15,
'discount_type' => 'percent',
'product_categories' => [ $cat_a, $cat_b ],
'excluded_product_categories' => [ $cat_c ],
]
);
$query = '
query ($id: ID!) {
coupon(id: $id) {
databaseId
productCategories {
nodes {
databaseId
slug
}
}
excludedProductCategories {
nodes {
databaseId
slug
}
}
}
}
';
$variables = [ 'id' => $this->toRelayId( 'shop_coupon', $coupon_id ) ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedField( 'coupon.databaseId', $coupon_id ),
$this->expectedNode(
'coupon.productCategories.nodes',
[ $this->expectedField( 'slug', 'cat-a' ) ]
),
$this->expectedNode(
'coupon.productCategories.nodes',
[ $this->expectedField( 'slug', 'cat-b' ) ]
),
$this->not()->expectedNode(
'coupon.productCategories.nodes',
[ $this->expectedField( 'slug', 'cat-c' ) ]
),
$this->expectedNode(
'coupon.excludedProductCategories.nodes',
[ $this->expectedField( 'slug', 'cat-c' ) ]
),
$this->not()->expectedNode(
'coupon.excludedProductCategories.nodes',
[ $this->expectedField( 'slug', 'cat-a' ) ]
),
];
$this->assertQuerySuccessful( $response, $expected );
// Query with where arg to further filter the included categories.
$query_with_filter = '
query ($id: ID!, $exclude: [ID]) {
coupon(id: $id) {
productCategories(where: { exclude: $exclude }) {
nodes {
slug
}
}
}
}
';
$variables = [
'id' => $this->toRelayId( 'shop_coupon', $coupon_id ),
'exclude' => [ $cat_b ],
];
$response = $this->graphql(
[
'query' => $query_with_filter,
'variables' => $variables,
]
);
$expected = [
$this->expectedNode(
'coupon.productCategories.nodes',
[ $this->expectedField( 'slug', 'cat-a' ) ]
),
$this->not()->expectedNode(
'coupon.productCategories.nodes',
[ $this->expectedField( 'slug', 'cat-b' ) ]
),
];
$this->assertQuerySuccessful( $response, $expected );
}
2019-03-21 21:43:24 -04:00
}