mirror of
https://github.com/wp-graphql/wp-graphql-woocommerce.git
synced 2026-08-14 12:53:44 +02:00
1282 lines
33 KiB
PHP
1282 lines
33 KiB
PHP
<?php
|
|
|
|
class CartMutationsTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
|
|
// tests
|
|
public function testAddToCartMutationWithProduct() {
|
|
$product_id = $this->factory->product->createSimple();
|
|
|
|
$query = '
|
|
mutation( $input: AddToCartInput! ) {
|
|
addToCart( input: $input ) {
|
|
clientMutationId
|
|
cartItem {
|
|
key
|
|
product {
|
|
node {
|
|
id
|
|
}
|
|
}
|
|
variation {
|
|
node {
|
|
id
|
|
}
|
|
}
|
|
quantity
|
|
subtotal
|
|
subtotalTax
|
|
total
|
|
tax
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'productId' => $product_id,
|
|
'quantity' => 2,
|
|
],
|
|
];
|
|
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
// Confirm valid response
|
|
$this->assertResponseIsValid( $response );
|
|
|
|
// Get/validate cart item key.
|
|
$cart_item_key = $this->lodashGet( $response, 'data.addToCart.cartItem.key' );
|
|
$this->assertNotEmpty( $cart_item_key );
|
|
|
|
// Get cart item data.
|
|
$cart = \WC()->cart;
|
|
$cart_item = $cart->get_cart_item( $cart_item_key );
|
|
$this->assertNotEmpty( $cart_item );
|
|
|
|
$this->assertQuerySuccessful(
|
|
$response,
|
|
[
|
|
$this->expectedField( 'addToCart.clientMutationId', 'someId' ),
|
|
$this->expectedField( 'addToCart.cartItem.key', $cart_item_key ),
|
|
$this->expectedField( 'addToCart.cartItem.product.node.id', $this->toRelayId( 'post', $product_id ) ),
|
|
$this->expectedField( 'addToCart.cartItem.quantity', 2 ),
|
|
$this->expectedField( 'addToCart.cartItem.subtotal', wc_graphql_price( $cart_item['line_subtotal'] ) ),
|
|
$this->expectedField( 'addToCart.cartItem.subtotalTax', wc_graphql_price( $cart_item['line_subtotal_tax'] ) ),
|
|
$this->expectedField( 'addToCart.cartItem.total', wc_graphql_price( $cart_item['line_total'] ) ),
|
|
$this->expectedField( 'addToCart.cartItem.tax', wc_graphql_price( $cart_item['line_tax'] ) ),
|
|
]
|
|
);
|
|
}
|
|
|
|
public function testAddToCartMutationWithProductVariation() {
|
|
$ids = $this->factory->product_variation->createSome();
|
|
|
|
$query = '
|
|
mutation( $input: AddToCartInput! ) {
|
|
addToCart( input: $input ) {
|
|
clientMutationId
|
|
cartItem {
|
|
key
|
|
product {
|
|
node {
|
|
id
|
|
}
|
|
}
|
|
variation {
|
|
node {
|
|
id
|
|
}
|
|
}
|
|
quantity
|
|
subtotal
|
|
subtotalTax
|
|
total
|
|
tax
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'productId' => $ids['product'],
|
|
'quantity' => 3,
|
|
'variationId' => $ids['variations'][0],
|
|
'variation' => [
|
|
[
|
|
'attributeName' => 'color',
|
|
'attributeValue' => 'red',
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
// Confirm valid response
|
|
$this->assertResponseIsValid( $response );
|
|
|
|
// Get/validate cart item key.
|
|
$cart_item_key = $this->lodashGet( $response, 'data.addToCart.cartItem.key' );
|
|
$this->assertNotEmpty( $cart_item_key );
|
|
|
|
// Get cart item data.
|
|
$cart = \WC()->cart;
|
|
$cart_item = $cart->get_cart_item( $cart_item_key );
|
|
$this->assertNotEmpty( $cart_item );
|
|
|
|
$this->assertQuerySuccessful(
|
|
$response,
|
|
[
|
|
$this->expectedField( 'addToCart.clientMutationId', 'someId' ),
|
|
$this->expectedField( 'addToCart.cartItem.key', $cart_item_key ),
|
|
$this->expectedField( 'addToCart.cartItem.product.node.id', $this->toRelayId( 'post', $ids['product'] ) ),
|
|
$this->expectedField( 'addToCart.cartItem.variation.node.id', $this->toRelayId( 'post', $ids['variations'][0] ) ),
|
|
$this->expectedField( 'addToCart.cartItem.quantity', 3 ),
|
|
$this->expectedField( 'addToCart.cartItem.subtotal', wc_graphql_price( $cart_item['line_subtotal'] ) ),
|
|
$this->expectedField( 'addToCart.cartItem.subtotalTax', wc_graphql_price( $cart_item['line_subtotal_tax'] ) ),
|
|
$this->expectedField( 'addToCart.cartItem.total', wc_graphql_price( $cart_item['line_total'] ) ),
|
|
$this->expectedField( 'addToCart.cartItem.tax', wc_graphql_price( $cart_item['line_tax'] ) ),
|
|
]
|
|
);
|
|
}
|
|
|
|
public function testUpdateCartItemQuantitiesMutation() {
|
|
// Create/add some products to the cart.
|
|
$cart_item_data = [
|
|
[
|
|
'product_id' => $this->factory->product->createSimple(),
|
|
'quantity' => 2,
|
|
],
|
|
[
|
|
'product_id' => $this->factory->product->createSimple(),
|
|
'quantity' => 5,
|
|
],
|
|
[
|
|
'product_id' => $this->factory->product->createSimple(),
|
|
'quantity' => 1,
|
|
],
|
|
];
|
|
|
|
// Store cart item keys for use in mutation.
|
|
$keys = $this->factory->cart->add( ...$cart_item_data );
|
|
|
|
// Define mutation.
|
|
$query = '
|
|
mutation( $input: UpdateItemQuantitiesInput! ) {
|
|
updateItemQuantities( input: $input ) {
|
|
clientMutationId
|
|
updated {
|
|
key
|
|
quantity
|
|
}
|
|
removed {
|
|
key
|
|
quantity
|
|
}
|
|
items {
|
|
key
|
|
quantity
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
// Define variables
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'items' => [
|
|
[
|
|
'key' => $keys[0],
|
|
'quantity' => 4,
|
|
],
|
|
[
|
|
'key' => $keys[1],
|
|
'quantity' => 2,
|
|
],
|
|
[
|
|
'key' => $keys[2],
|
|
'quantity' => 0,
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
// Execute mutation.
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
$this->assertQuerySuccessful(
|
|
$response,
|
|
[
|
|
$this->expectedField( 'updateItemQuantities.clientMutationId', 'someId' ),
|
|
$this->expectedNode(
|
|
'updateItemQuantities.updated',
|
|
[
|
|
'key' => $keys[0],
|
|
'quantity' => 4,
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'updateItemQuantities.updated',
|
|
[
|
|
'key' => $keys[1],
|
|
'quantity' => 2,
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'updateItemQuantities.removed',
|
|
[
|
|
'key' => $keys[2],
|
|
'quantity' => 1,
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'updateItemQuantities.items',
|
|
[
|
|
'key' => $keys[0],
|
|
'quantity' => 4,
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'updateItemQuantities.items',
|
|
[
|
|
'key' => $keys[1],
|
|
'quantity' => 2,
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'updateItemQuantities.items',
|
|
[
|
|
'key' => $keys[2],
|
|
'quantity' => 1,
|
|
]
|
|
),
|
|
]
|
|
);
|
|
}
|
|
|
|
public function testRemoveItemsFromCartMutation() {
|
|
// Create/add some products to the cart.
|
|
$cart_item_data = [
|
|
[
|
|
'product_id' => $this->factory->product->createSimple(),
|
|
'quantity' => 2,
|
|
],
|
|
[
|
|
'product_id' => $this->factory->product->createSimple(),
|
|
'quantity' => 5,
|
|
],
|
|
[
|
|
'product_id' => $this->factory->product->createSimple(),
|
|
'quantity' => 1,
|
|
],
|
|
];
|
|
|
|
// Store cart item keys for use in mutation.
|
|
$keys = $this->factory->cart->add( ...$cart_item_data );
|
|
|
|
$query = '
|
|
mutation( $input: RemoveItemsFromCartInput! ) {
|
|
removeItemsFromCart( input: $input ) {
|
|
clientMutationId
|
|
cartItems {
|
|
key
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
// Define expected response data.
|
|
$expected = [ $this->expectedField( 'removeItemsFromCart.clientMutationId', 'someId' ) ];
|
|
foreach ( $keys as $key ) {
|
|
$expected[] = $this->expectedNode( 'removeItemsFromCart.cartItems', compact( 'key' ) );
|
|
}
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'keys' => $keys,
|
|
],
|
|
];
|
|
|
|
// Execute mutation w/ "keys" array.
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
$this->assertQuerySuccessful( $response, $expected );
|
|
|
|
// Confirm none of the items in cart.
|
|
foreach ( $keys as $key ) {
|
|
$this->assertEmpty(
|
|
\WC()->cart->get_cart_item( $key ),
|
|
"{$key} still in cart after \"removeItemsFromCart\" mutation."
|
|
);
|
|
}
|
|
|
|
// Add more items and execute mutation with "all" flag.
|
|
$keys = $this->factory->cart->add( ...$cart_item_data );
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'all' => true,
|
|
],
|
|
];
|
|
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
$this->assertQuerySuccessful( $response, $expected );
|
|
|
|
// Confirm none of the items in cart.
|
|
foreach ( $keys as $key ) {
|
|
$this->assertEmpty(
|
|
\WC()->cart->get_cart_item( $key ),
|
|
"{$key} still in cart after \"removeItemsFromCart\" mutation with \"all\" flag."
|
|
);
|
|
}
|
|
}
|
|
|
|
public function testRestoreCartItemsMutation() {
|
|
// Create/add some products to the cart.
|
|
$cart_item_data = [
|
|
[
|
|
'product_id' => $this->factory->product->createSimple(),
|
|
'quantity' => 2,
|
|
],
|
|
[
|
|
'product_id' => $this->factory->product->createSimple(),
|
|
'quantity' => 5,
|
|
],
|
|
[
|
|
'product_id' => $this->factory->product->createSimple(),
|
|
'quantity' => 1,
|
|
],
|
|
];
|
|
$keys = $this->factory->cart->add( ...$cart_item_data );
|
|
$this->factory->cart->remove( ...$keys );
|
|
|
|
$query = '
|
|
mutation( $input: RestoreCartItemsInput! ) {
|
|
restoreCartItems( input: $input ) {
|
|
clientMutationId
|
|
cartItems {
|
|
key
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'keys' => $keys,
|
|
],
|
|
];
|
|
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
$expected = [ $this->expectedField( 'restoreCartItems.clientMutationId', 'someId' ) ];
|
|
foreach ( $keys as $key ) {
|
|
$expected[] = $this->expectedNode( 'restoreCartItems.cartItems', compact( 'key' ) );
|
|
}
|
|
|
|
$this->assertQuerySuccessful( $response, $expected );
|
|
|
|
// Confirm items in cart.
|
|
foreach ( $keys as $key ) {
|
|
$this->assertNotEmpty(
|
|
\WC()->cart->get_cart_item( $key ),
|
|
"{$key} not found in cart after \"restoreCartItems\" mutation."
|
|
);
|
|
}
|
|
}
|
|
|
|
public function testEmptyCartMutation() {
|
|
// Create/add some products to the cart.
|
|
$product_id = $this->factory->product->createSimple();
|
|
$cart = \WC()->cart;
|
|
$cart_item_key = $cart->add_to_cart( $product_id, 1 );
|
|
$cart_item = $cart->get_cart_item( $cart_item_key );
|
|
|
|
$query = '
|
|
mutation( $input: EmptyCartInput! ) {
|
|
emptyCart( input: $input ) {
|
|
clientMutationId
|
|
deletedCart {
|
|
contents {
|
|
nodes {
|
|
key
|
|
product {
|
|
node {
|
|
id
|
|
}
|
|
}
|
|
variation {
|
|
node {
|
|
id
|
|
}
|
|
}
|
|
quantity
|
|
subtotal
|
|
subtotalTax
|
|
total
|
|
tax
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$variables = [
|
|
'input' => [ 'clientMutationId' => 'someId' ],
|
|
];
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
$this->assertQuerySuccessful(
|
|
$response,
|
|
[
|
|
$this->expectedField( 'emptyCart.clientMutationId', 'someId' ),
|
|
$this->expectedNode(
|
|
'emptyCart.deletedCart.contents.nodes',
|
|
[
|
|
'key' => $cart_item['key'],
|
|
'product' => [
|
|
'node' => [
|
|
'id' => $this->toRelayId( 'post', $cart_item['product_id'] ),
|
|
],
|
|
],
|
|
'variation' => null,
|
|
'quantity' => $cart_item['quantity'],
|
|
'subtotal' => wc_graphql_price( $cart_item['line_subtotal'] ),
|
|
'subtotalTax' => wc_graphql_price( $cart_item['line_subtotal_tax'] ),
|
|
'total' => wc_graphql_price( $cart_item['line_total'] ),
|
|
'tax' => wc_graphql_price( $cart_item['line_tax'] ),
|
|
]
|
|
),
|
|
]
|
|
);
|
|
|
|
$this->assertTrue( \WC()->cart->is_empty() );
|
|
}
|
|
|
|
public function testApplyCouponMutation() {
|
|
// Create products.
|
|
$product_id = $this->factory->product->createSimple(
|
|
[ 'regular_price' => 100 ]
|
|
);
|
|
|
|
// Create coupon.
|
|
$coupon_code = wc_get_coupon_code_by_id(
|
|
$this->factory->coupon->create(
|
|
[
|
|
'amount' => 0.5,
|
|
'product_ids' => [ $product_id ],
|
|
'description' => 'lorem ipsum dolor',
|
|
]
|
|
)
|
|
);
|
|
|
|
// Add items to carts.
|
|
$cart = \WC()->cart;
|
|
$cart_item_key = $cart->add_to_cart( $product_id, 1 );
|
|
|
|
$old_total = \WC()->cart->get_cart_contents_total();
|
|
|
|
$query = '
|
|
mutation( $input: ApplyCouponInput! ) {
|
|
applyCoupon( input: $input ) {
|
|
clientMutationId
|
|
cart {
|
|
appliedCoupons {
|
|
code
|
|
description
|
|
}
|
|
contents {
|
|
nodes {
|
|
key
|
|
product {
|
|
node {
|
|
id
|
|
}
|
|
}
|
|
quantity
|
|
subtotal
|
|
subtotalTax
|
|
total
|
|
tax
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'code' => $coupon_code,
|
|
],
|
|
];
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
// Get updated cart item.
|
|
$cart_item = $cart->get_cart_item( $cart_item_key );
|
|
|
|
$this->assertQuerySuccessful(
|
|
$response,
|
|
[
|
|
$this->expectedField( 'applyCoupon.clientMutationId', 'someId' ),
|
|
$this->expectedNode(
|
|
'applyCoupon.cart.appliedCoupons',
|
|
[
|
|
'code' => $coupon_code,
|
|
'description' => 'lorem ipsum dolor',
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'applyCoupon.cart.contents.nodes',
|
|
[
|
|
'key' => $cart_item['key'],
|
|
'product' => [
|
|
'node' => [
|
|
'id' => $this->toRelayId( 'post', $cart_item['product_id'] ),
|
|
],
|
|
],
|
|
'quantity' => $cart_item['quantity'],
|
|
'subtotal' => wc_graphql_price( $cart_item['line_subtotal'] ),
|
|
'subtotalTax' => wc_graphql_price( $cart_item['line_subtotal_tax'] ),
|
|
'total' => wc_graphql_price( $cart_item['line_total'] ),
|
|
'tax' => wc_graphql_price( $cart_item['line_tax'] ),
|
|
]
|
|
),
|
|
]
|
|
);
|
|
|
|
$new_total = \WC()->cart->get_cart_contents_total();
|
|
|
|
// Use --debug to view.
|
|
codecept_debug(
|
|
[
|
|
'old' => $old_total,
|
|
'new' => $new_total,
|
|
]
|
|
);
|
|
|
|
$this->assertTrue( $old_total > $new_total );
|
|
}
|
|
|
|
public function testApplyCouponMutationWithInvalidCoupons() {
|
|
$cart = WC()->cart;
|
|
|
|
// Create products.
|
|
$product_id = $this->factory->product->createSimple();
|
|
|
|
// Create invalid coupon codes.
|
|
$coupon_id = $this->factory->coupon->create(
|
|
[ 'product_ids' => [ $product_id ] ]
|
|
);
|
|
$expired_coupon_code = wc_get_coupon_code_by_id(
|
|
$this->factory->coupon->create(
|
|
[
|
|
'product_ids' => [ $product_id ],
|
|
'date_expires' => time() - 20,
|
|
]
|
|
)
|
|
);
|
|
$applied_coupon_code = wc_get_coupon_code_by_id(
|
|
$this->factory->coupon->create(
|
|
[ 'product_ids' => [ $product_id ] ]
|
|
)
|
|
);
|
|
|
|
// Add items to carts.
|
|
$cart_item_key = $cart->add_to_cart( $product_id, 1 );
|
|
$cart->apply_coupon( $applied_coupon_code );
|
|
|
|
$old_total = \WC()->cart->get_cart_contents_total();
|
|
|
|
$query = '
|
|
mutation( $input: ApplyCouponInput! ) {
|
|
applyCoupon( input: $input ) {
|
|
clientMutationId
|
|
}
|
|
}
|
|
';
|
|
|
|
/**
|
|
* Assertion One
|
|
*
|
|
* Can't pass coupon ID as coupon 'code'. Mutation should fail.
|
|
*/
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'code' => '$coupon_id',
|
|
],
|
|
];
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
$this->assertNotEmpty( $response['errors'] );
|
|
$this->assertEmpty( $response['data']['applyCoupon'] );
|
|
|
|
/**
|
|
* Assertion Two
|
|
*
|
|
* Can't pass expired coupon code. Mutation should fail.
|
|
*/
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'code' => $expired_coupon_code,
|
|
],
|
|
];
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
$this->assertNotEmpty( $response['errors'] );
|
|
$this->assertEmpty( $response['data']['applyCoupon'] );
|
|
|
|
/**
|
|
* Assertion Three
|
|
*
|
|
* Can't pass coupon already applied to the cart. Mutation should fail.
|
|
*/
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'code' => $applied_coupon_code,
|
|
],
|
|
];
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
$this->assertNotEmpty( $response['errors'] );
|
|
$this->assertEmpty( $response['data']['applyCoupon'] );
|
|
|
|
$this->assertEquals( $old_total, \WC()->cart->get_cart_contents_total() );
|
|
}
|
|
|
|
public function testRemoveCouponMutation() {
|
|
// Create product and coupon.
|
|
$product_id = $this->factory->product->createSimple();
|
|
$coupon_code = wc_get_coupon_code_by_id(
|
|
$this->factory->coupon->create(
|
|
[ 'product_ids' => [ $product_id ] ]
|
|
)
|
|
);
|
|
|
|
// Add item and coupon to cart and get total..
|
|
$cart = \WC()->cart;
|
|
$cart_item_key = $cart->add_to_cart( $product_id, 3 );
|
|
$cart->apply_coupon( $coupon_code );
|
|
|
|
$query = '
|
|
mutation removeCoupons( $input: RemoveCouponsInput! ) {
|
|
removeCoupons( input: $input ) {
|
|
clientMutationId
|
|
cart {
|
|
appliedCoupons {
|
|
code
|
|
}
|
|
contents {
|
|
nodes {
|
|
key
|
|
product {
|
|
node {
|
|
id
|
|
}
|
|
}
|
|
quantity
|
|
subtotal
|
|
subtotalTax
|
|
total
|
|
tax
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'codes' => [ $coupon_code ],
|
|
],
|
|
];
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
// Get updated cart item.
|
|
$cart_item = \WC()->cart->get_cart_item( $cart_item_key );
|
|
|
|
$this->assertQuerySuccessful(
|
|
$response,
|
|
[
|
|
$this->expectedField( 'removeCoupons.clientMutationId', 'someId' ),
|
|
$this->expectedField( 'removeCoupons.cart.appliedCoupons', static::IS_NULL ),
|
|
$this->expectedNode(
|
|
'removeCoupons.cart.contents.nodes',
|
|
[
|
|
'key' => $cart_item['key'],
|
|
'product' => [
|
|
'node' => [
|
|
'id' => $this->toRelayId( 'post', $cart_item['product_id'] ),
|
|
],
|
|
],
|
|
'quantity' => $cart_item['quantity'],
|
|
'subtotal' => wc_graphql_price( $cart_item['line_subtotal'] ),
|
|
'subtotalTax' => wc_graphql_price( $cart_item['line_subtotal_tax'] ),
|
|
'total' => wc_graphql_price( $cart_item['line_total'] ),
|
|
'tax' => wc_graphql_price( $cart_item['line_tax'] ),
|
|
]
|
|
),
|
|
]
|
|
);
|
|
}
|
|
|
|
public function testAddFeeMutation() {
|
|
// Create product and coupon.
|
|
$product_id = $this->factory->product->createSimple();
|
|
$coupon_code = wc_get_coupon_code_by_id(
|
|
$this->factory->coupon->create(
|
|
[ 'product_ids' => [ $product_id ] ]
|
|
)
|
|
);
|
|
|
|
// Add item and coupon to cart.
|
|
$cart = \WC()->cart;
|
|
$cart->add_to_cart( $product_id, 3 );
|
|
$cart->apply_coupon( $coupon_code );
|
|
|
|
$query = '
|
|
mutation( $input: AddFeeInput! ) {
|
|
addFee( input: $input ) {
|
|
clientMutationId
|
|
cartFee {
|
|
id
|
|
name
|
|
taxClass
|
|
taxable
|
|
amount
|
|
total
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'name' => 'extra_fee',
|
|
'amount' => 49.99,
|
|
],
|
|
];
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
$this->assertArrayHasKey( 'errors', $response );
|
|
|
|
wp_set_current_user( $this->shop_manager );
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
$cart = WC()->cart;
|
|
$fee = ( $cart->get_fees() )['extra_fee'];
|
|
|
|
$this->assertQuerySuccessful(
|
|
$response,
|
|
[
|
|
$this->expectedField( 'addFee.clientMutationId', 'someId' ),
|
|
$this->expectedField(
|
|
'addFee.cartFee',
|
|
[
|
|
'id' => $fee->id,
|
|
'name' => $fee->name,
|
|
'taxClass' => ! empty( $fee->tax_class ) ? $fee->tax_class : null,
|
|
'taxable' => $fee->taxable,
|
|
'amount' => (float) $fee->amount,
|
|
'total' => (float) $fee->total,
|
|
]
|
|
),
|
|
]
|
|
);
|
|
}
|
|
|
|
public function testAddToCartMutationErrors() {
|
|
// Create products.
|
|
$product_id = $this->factory->product->createSimple(
|
|
[
|
|
'manage_stock' => true,
|
|
'stock_quantity' => 1,
|
|
]
|
|
);
|
|
$variation_ids = $this->factory->product_variation->createSome();
|
|
|
|
$product = \wc_get_product( $variation_ids['product'] );
|
|
$attribute = new WC_Product_Attribute();
|
|
$attribute->set_id( 0 );
|
|
$attribute->set_name( 'test' );
|
|
$attribute->set_options( [ 'yes', 'no' ] );
|
|
$attribute->set_position( 3 );
|
|
$attribute->set_visible( true );
|
|
$attribute->set_variation( true );
|
|
$attributes = array_values( $product->get_attributes() );
|
|
$attributes[] = $attribute;
|
|
$product->set_attributes( $attributes );
|
|
$product->save();
|
|
|
|
$query = '
|
|
mutation( $input: AddToCartInput! ) {
|
|
addToCart( input: $input ) {
|
|
clientMutationId
|
|
cartItem {
|
|
key
|
|
product {
|
|
node {
|
|
id
|
|
}
|
|
}
|
|
variation {
|
|
node {
|
|
id
|
|
}
|
|
}
|
|
quantity
|
|
subtotal
|
|
subtotalTax
|
|
total
|
|
tax
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
\WC()->session->set( 'wc_notices', null );
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'productId' => $variation_ids['product'],
|
|
'quantity' => 5,
|
|
'variationId' => $variation_ids['variations'][0],
|
|
],
|
|
];
|
|
$missing_attributes = $this->graphql( compact( 'query', 'variables' ) );
|
|
$this->assertArrayHasKey( 'errors', $missing_attributes );
|
|
|
|
\WC()->session->set( 'wc_notices', null );
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'productId' => $product_id,
|
|
'quantity' => 5,
|
|
],
|
|
];
|
|
$not_enough_stock = $this->graphql( compact( 'query', 'variables' ) );
|
|
$this->assertArrayHasKey( 'errors', $not_enough_stock );
|
|
}
|
|
|
|
public function testAddToCartMutationItemEdgeData() {
|
|
// Create variable product for later use.
|
|
$variation_ids = $this->factory->product_variation->createSome();
|
|
$product = \wc_get_product( $variation_ids['product'] );
|
|
$attribute = new WC_Product_Attribute();
|
|
$attribute->set_id( 0 );
|
|
$attribute->set_name( 'test' );
|
|
$attribute->set_options( [ 'yes', 'no' ] );
|
|
$attribute->set_position( 3 );
|
|
$attribute->set_visible( true );
|
|
$attribute->set_variation( true );
|
|
$attributes = array_values( $product->get_attributes() );
|
|
$attributes[] = $attribute;
|
|
$product->set_attributes( $attributes );
|
|
$product->save();
|
|
|
|
$query = '
|
|
mutation( $input: AddToCartInput! ) {
|
|
addToCart(input: $input) {
|
|
cartItem {
|
|
product {
|
|
simpleVariations {
|
|
name
|
|
value
|
|
}
|
|
node {
|
|
databaseId
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'productId' => $variation_ids['product'],
|
|
'quantity' => 3,
|
|
'variationId' => $variation_ids['variations'][1],
|
|
'variation' => [
|
|
[
|
|
'attributeName' => 'test',
|
|
'attributeValue' => 'yes',
|
|
],
|
|
[
|
|
'attributeName' => 'color',
|
|
'attributeValue' => 'green',
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
$expected = [
|
|
$this->expectedObject(
|
|
'addToCart.cartItem.product',
|
|
[
|
|
$this->expectedField( 'node.databaseId', $variation_ids['product'] ),
|
|
$this->expectedObject(
|
|
'simpleVariations.#',
|
|
[
|
|
$this->expectedField( 'name', 'attribute_test' ),
|
|
$this->expectedField( 'value', 'yes' ),
|
|
]
|
|
),
|
|
$this->expectedObject(
|
|
'simpleVariations.#',
|
|
[
|
|
$this->expectedField( 'name', 'attribute_pa_color' ),
|
|
$this->expectedField( 'value', 'green' ),
|
|
]
|
|
),
|
|
]
|
|
),
|
|
];
|
|
|
|
$this->assertQuerySuccessful( $response, $expected );
|
|
}
|
|
|
|
public function testAddCartItemsMutationAndErrors() {
|
|
// Create variable product for later use.
|
|
$variation_ids = $this->factory->product_variation->createSome();
|
|
$product = \wc_get_product( $variation_ids['product'] );
|
|
$attribute = new WC_Product_Attribute();
|
|
$attribute->set_id( 0 );
|
|
$attribute->set_name( 'test' );
|
|
$attribute->set_options( [ 'yes', 'no' ] );
|
|
$attribute->set_position( 3 );
|
|
$attribute->set_visible( true );
|
|
$attribute->set_variation( true );
|
|
$attributes = array_values( $product->get_attributes() );
|
|
$attributes[] = $attribute;
|
|
$product->set_attributes( $attributes );
|
|
$product->save();
|
|
|
|
$product_one = $this->factory->product->createSimple();
|
|
$invalid_product = 1000;
|
|
|
|
$query = '
|
|
mutation ($input: AddCartItemsInput!) {
|
|
addCartItems(input: $input) {
|
|
clientMutationId
|
|
added {
|
|
product {
|
|
node { databaseId }
|
|
}
|
|
variation {
|
|
node { databaseId }
|
|
}
|
|
quantity
|
|
}
|
|
cartErrors {
|
|
type
|
|
reasons
|
|
productId
|
|
quantity
|
|
variationId
|
|
variation {
|
|
attributeName
|
|
attributeValue
|
|
}
|
|
extraData
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'items' => [
|
|
[
|
|
'productId' => $product_one,
|
|
'quantity' => 2,
|
|
],
|
|
[
|
|
'productId' => $variation_ids['product'],
|
|
'quantity' => 5,
|
|
'variationId' => $variation_ids['variations'][0],
|
|
],
|
|
[
|
|
'productId' => $invalid_product,
|
|
'quantity' => 4,
|
|
],
|
|
[
|
|
'productId' => $variation_ids['product'],
|
|
'quantity' => 3,
|
|
'variationId' => $variation_ids['variations'][1],
|
|
'variation' => [
|
|
[
|
|
'attributeName' => 'test',
|
|
'attributeValue' => 'yes',
|
|
],
|
|
[
|
|
'attributeName' => 'color',
|
|
'attributeValue' => 'green',
|
|
],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
|
|
$this->assertQuerySuccessful(
|
|
$response,
|
|
[
|
|
$this->expectedField( 'addCartItems.clientMutationId', 'someId' ),
|
|
$this->expectedNode(
|
|
'addCartItems.added',
|
|
[
|
|
'product' => [
|
|
'node' => [ 'databaseId' => $product_one ],
|
|
],
|
|
'variation' => null,
|
|
'quantity' => 2,
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'addCartItems.added',
|
|
[
|
|
'product' => [
|
|
'node' => [ 'databaseId' => $variation_ids['product'] ],
|
|
],
|
|
'variation' => [
|
|
'node' => [ 'databaseId' => $variation_ids['variations'][1] ],
|
|
],
|
|
'quantity' => 3,
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'addCartItems.cartErrors',
|
|
[
|
|
$this->expectedField( 'type', 'INVALID_CART_ITEM' ),
|
|
$this->expectedField( 'reasons.0', static::NOT_NULL ),
|
|
$this->expectedField( 'productId', $variation_ids['product'] ),
|
|
$this->expectedField( 'quantity', 5 ),
|
|
$this->expectedField( 'variationId', $variation_ids['variations'][0] ),
|
|
$this->expectedField( 'variation', static::IS_NULL ),
|
|
$this->expectedField( 'extraData', static::IS_NULL ),
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'addCartItems.cartErrors',
|
|
[
|
|
$this->expectedField( 'type', 'INVALID_CART_ITEM' ),
|
|
$this->expectedField( 'reasons.0', 'No product found matching the ID provided' ),
|
|
$this->expectedField( 'productId', $invalid_product ),
|
|
$this->expectedField( 'quantity', 4 ),
|
|
$this->expectedField( 'variationId', static::IS_NULL ),
|
|
$this->expectedField( 'variation', static::IS_NULL ),
|
|
$this->expectedField( 'extraData', static::IS_NULL ),
|
|
]
|
|
),
|
|
]
|
|
);
|
|
}
|
|
|
|
public function testFillCartMutationAndErrors() {
|
|
// Create products.
|
|
$product_one = $this->factory->product->createSimple( [ 'regular_price' => 100 ] );
|
|
$product_two = $this->factory->product->createSimple( [ 'regular_price' => 40 ] );
|
|
|
|
// Create coupons.
|
|
$coupon_code_one = wc_get_coupon_code_by_id(
|
|
$this->factory->coupon->create(
|
|
[
|
|
'amount' => 0.5,
|
|
'product_ids' => [ $product_one ],
|
|
]
|
|
)
|
|
);
|
|
$coupon_code_two = wc_get_coupon_code_by_id(
|
|
$this->factory->coupon->create(
|
|
[
|
|
'amount' => 0.2,
|
|
'product_ids' => [ $product_two ],
|
|
]
|
|
)
|
|
);
|
|
|
|
$invalid_product = 1000;
|
|
$invalid_coupon = 'failed';
|
|
$invalid_shipping_method = 'fakityfake-shipping';
|
|
|
|
$this->factory->shipping_zone->createLegacyFlatRate();
|
|
|
|
$query = '
|
|
mutation ($input: FillCartInput!) {
|
|
fillCart( input: $input ) {
|
|
clientMutationId
|
|
cart {
|
|
chosenShippingMethods
|
|
contents {
|
|
nodes {
|
|
product {
|
|
node { databaseId }
|
|
}
|
|
quantity
|
|
variation {
|
|
node { databaseId }
|
|
}
|
|
}
|
|
}
|
|
appliedCoupons {
|
|
code
|
|
discountAmount
|
|
discountTax
|
|
}
|
|
}
|
|
cartErrors {
|
|
type
|
|
... on CartItemError {
|
|
reasons
|
|
productId
|
|
quantity
|
|
}
|
|
... on CouponError {
|
|
reasons
|
|
code
|
|
}
|
|
... on ShippingMethodError {
|
|
chosenMethod
|
|
package
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$variables = [
|
|
'input' => [
|
|
'clientMutationId' => 'someId',
|
|
'items' => [
|
|
[
|
|
'productId' => $product_one,
|
|
'quantity' => 3,
|
|
],
|
|
[
|
|
'productId' => $product_two,
|
|
'quantity' => 2,
|
|
],
|
|
[
|
|
'productId' => $invalid_product,
|
|
'quantity' => 4,
|
|
],
|
|
],
|
|
'coupons' => [ $coupon_code_one, $coupon_code_two, $invalid_coupon ],
|
|
'shippingMethods' => [ 'legacy_flat_rate', $invalid_shipping_method ],
|
|
],
|
|
];
|
|
|
|
$response = $this->graphql( compact( 'query', 'variables' ) );
|
|
$expected = [
|
|
$this->expectedObject(
|
|
'fillCart',
|
|
[
|
|
$this->expectedField( 'clientMutationId', 'someId' ),
|
|
$this->expectedObject(
|
|
'cart',
|
|
[
|
|
$this->expectedField( 'chosenShippingMethods.0', 'legacy_flat_rate' ),
|
|
$this->expectedObject(
|
|
'contents',
|
|
[
|
|
$this->expectedNode(
|
|
'nodes',
|
|
[
|
|
$this->expectedField( 'product.node.databaseId', $product_one ),
|
|
$this->expectedField( 'quantity', 3 ),
|
|
$this->expectedField( 'variation', self::IS_NULL ),
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'nodes',
|
|
[
|
|
$this->expectedField( 'product.node.databaseId', $product_two ),
|
|
$this->expectedField( 'quantity', 2 ),
|
|
$this->expectedField( 'variation', self::IS_NULL ),
|
|
]
|
|
),
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'appliedCoupons',
|
|
[
|
|
$this->expectedField( 'code', $coupon_code_one ),
|
|
$this->expectedField(
|
|
'discountAmount',
|
|
\wc_graphql_price( \WC()->cart->get_coupon_discount_amount( $coupon_code_one, true ) )
|
|
),
|
|
$this->expectedField(
|
|
'discountTax',
|
|
\wc_graphql_price( \WC()->cart->get_coupon_discount_tax_amount( $coupon_code_one ) )
|
|
),
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'appliedCoupons',
|
|
[
|
|
$this->expectedField( 'code', $coupon_code_two ),
|
|
$this->expectedField(
|
|
'discountAmount',
|
|
\wc_graphql_price( \WC()->cart->get_coupon_discount_amount( $coupon_code_two, true ) )
|
|
),
|
|
$this->expectedField(
|
|
'discountTax',
|
|
\wc_graphql_price( \WC()->cart->get_coupon_discount_tax_amount( $coupon_code_two ) )
|
|
),
|
|
]
|
|
),
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'cartErrors',
|
|
[
|
|
$this->expectedField( 'type', 'INVALID_CART_ITEM' ),
|
|
$this->expectedField( 'reasons', [ 'No product found matching the ID provided' ] ),
|
|
$this->expectedField( 'productId', $invalid_product ),
|
|
$this->expectedField( 'quantity', 4 ),
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'cartErrors',
|
|
[
|
|
$this->expectedField( 'type', 'INVALID_COUPON' ),
|
|
$this->expectedField( 'reasons', [ "Coupon \"{$invalid_coupon}\" does not exist!" ] ),
|
|
$this->expectedField( 'code', $invalid_coupon ),
|
|
]
|
|
),
|
|
$this->expectedNode(
|
|
'cartErrors',
|
|
[
|
|
$this->expectedField( 'type', 'INVALID_SHIPPING_METHOD' ),
|
|
$this->expectedField( 'chosenMethod', $invalid_shipping_method ),
|
|
$this->expectedField( 'package', 1 ),
|
|
]
|
|
),
|
|
]
|
|
),
|
|
];
|
|
|
|
$this->assertQuerySuccessful( $response, $expected );
|
|
}
|
|
}
|