mirror of
https://github.com/wp-graphql/wp-graphql-woocommerce.git
synced 2026-08-14 12:53:44 +02:00
576 lines
20 KiB
PHP
576 lines
20 KiB
PHP
<?php
|
|
|
|
use Firebase\JWT\JWT;
|
|
|
|
class QLSessionHandlerCest {
|
|
private $product_catalog;
|
|
|
|
public function _before( FunctionalTester $I ) {
|
|
// Create Products
|
|
$this->product_catalog = $I->getCatalog();
|
|
}
|
|
|
|
// tests
|
|
public function testCartMutationsWithValidCartSessionToken( FunctionalTester $I ) {
|
|
/**
|
|
* Add item to the cart
|
|
*/
|
|
$success = $I->addToCart(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'productId' => $this->product_catalog['t-shirt'],
|
|
'quantity' => 5,
|
|
)
|
|
);
|
|
|
|
$I->assertArrayNotHasKey( 'errors', $success );
|
|
$I->assertArrayHasKey('data', $success );
|
|
$I->assertArrayHasKey('addToCart', $success['data'] );
|
|
$I->assertArrayHasKey('cartItem', $success['data']['addToCart'] );
|
|
$I->assertArrayHasKey('key', $success['data']['addToCart']['cartItem'] );
|
|
$cart_item_key = $success['data']['addToCart']['cartItem']['key'];
|
|
|
|
/**
|
|
* Assert existence and validity of "woocommerce-session" HTTP header.
|
|
*/
|
|
$I->seeHttpHeaderOnce( 'woocommerce-session' );
|
|
$session_token = $I->grabHttpHeader( 'woocommerce-session' );
|
|
|
|
// Decode token
|
|
JWT::$leeway = 60;
|
|
$token_data = ! empty( $session_token )
|
|
? JWT::decode( $session_token, 'graphql-woo-cart-session', array( 'HS256' ) )
|
|
: null;
|
|
|
|
$I->assertNotEmpty( $token_data );
|
|
$I->assertNotEmpty( $token_data->iss );
|
|
$I->assertNotEmpty( $token_data->iat );
|
|
$I->assertNotEmpty( $token_data->nbf );
|
|
$I->assertNotEmpty( $token_data->exp );
|
|
$I->assertNotEmpty( $token_data->data );
|
|
$I->assertNotEmpty( $token_data->data->customer_id );
|
|
|
|
$wp_url = getenv( 'WP_URL' );
|
|
$I->assertEquals( $token_data->iss, $wp_url );
|
|
|
|
/**
|
|
* Make a cart query request with "woocommerce-session" HTTP Header and confirm
|
|
* correct cart contents.
|
|
*/
|
|
$query = '
|
|
query {
|
|
cart {
|
|
contents {
|
|
nodes {
|
|
key
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$actual = $I->sendGraphQLRequest( $query, null, array( 'woocommerce-session' => "Session {$session_token}" ) );
|
|
$expected = array(
|
|
'data' => array(
|
|
'cart' => array(
|
|
'contents' => array(
|
|
'nodes' => array(
|
|
array(
|
|
'key' => $cart_item_key,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
$I->assertEquals( $expected, $actual );
|
|
|
|
/**
|
|
* Remove item from the cart
|
|
*/
|
|
$success = $I->removeItemsFromCart(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'keys' => $cart_item_key,
|
|
),
|
|
array( 'woocommerce-session' => "Session {$session_token}" )
|
|
);
|
|
|
|
$I->assertArrayNotHasKey( 'errors', $success );
|
|
$I->assertArrayHasKey('data', $success );
|
|
$I->assertArrayHasKey('removeItemsFromCart', $success['data'] );
|
|
$I->assertArrayHasKey('cartItems', $success['data']['removeItemsFromCart'] );
|
|
$I->assertCount( 1, $success['data']['removeItemsFromCart']['cartItems'] );
|
|
|
|
/**
|
|
* Make a cart query request with "woocommerce-session" HTTP Header and confirm
|
|
* correct cart contents.
|
|
*/
|
|
$query = '
|
|
query {
|
|
cart {
|
|
contents {
|
|
nodes {
|
|
key
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$actual = $I->sendGraphQLRequest( $query, null, array( 'woocommerce-session' => "Session {$session_token}" ) );
|
|
$expected = array(
|
|
'data' => array(
|
|
'cart' => array(
|
|
'contents' => array(
|
|
'nodes' => array(),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
$I->assertEquals( $expected, $actual );
|
|
|
|
/**
|
|
* Restore item to the cart
|
|
*/
|
|
$success = $I->restoreCartItems(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'keys' => array( $cart_item_key ),
|
|
),
|
|
array( 'woocommerce-session' => "Session {$session_token}" )
|
|
);
|
|
|
|
$I->assertArrayNotHasKey( 'errors', $success );
|
|
$I->assertArrayHasKey('data', $success );
|
|
$I->assertArrayHasKey('restoreCartItems', $success['data'] );
|
|
$I->assertArrayHasKey('cartItems', $success['data']['restoreCartItems'] );
|
|
$I->assertCount( 1, $success['data']['restoreCartItems']['cartItems'] );
|
|
|
|
/**
|
|
* Make a cart query request with "woocommerce-session" HTTP Header and confirm
|
|
* correct cart contents.
|
|
*/
|
|
$query = '
|
|
query {
|
|
cart {
|
|
contents {
|
|
nodes {
|
|
key
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$actual = $I->sendGraphQLRequest( $query, null, array( 'woocommerce-session' => "Session {$session_token}" ) );
|
|
$expected = array(
|
|
'data' => array(
|
|
'cart' => array(
|
|
'contents' => array(
|
|
'nodes' => array(
|
|
array(
|
|
'key' => $cart_item_key,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
$I->assertEquals( $expected, $actual );
|
|
}
|
|
|
|
public function testCartMutationsWithInvalidCartSessionToken( FunctionalTester $I ) {
|
|
/**
|
|
* Add item to cart and retrieve session token to corrupt.
|
|
*/
|
|
$success = $I->addToCart(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'productId' => $this->product_catalog['t-shirt'],
|
|
'quantity' => 1,
|
|
)
|
|
);
|
|
|
|
$I->assertArrayNotHasKey( 'errors', $success );
|
|
$I->assertArrayHasKey('data', $success );
|
|
$I->assertArrayHasKey('addToCart', $success['data'] );
|
|
$I->assertArrayHasKey('cartItem', $success['data']['addToCart'] );
|
|
$I->assertArrayHasKey('key', $success['data']['addToCart']['cartItem'] );
|
|
$cart_item_key = $success['data']['addToCart']['cartItem']['key'];
|
|
|
|
/**
|
|
* Retrieve session token from "woocommerce-session" HTTP response header.
|
|
*/
|
|
$I->seeHttpHeaderOnce( 'woocommerce-session' );
|
|
$valid_token = $I->grabHttpHeader( 'woocommerce-session' );
|
|
|
|
// Decode token
|
|
$token_data = ! empty( $valid_token )
|
|
? JWT::decode( $valid_token, 'graphql-woo-cart-session', array( 'HS256' ) )
|
|
: null;
|
|
|
|
/**
|
|
* Attempt to add item to the cart with invalid session token.
|
|
* GraphQL should throw an error and mutation will fail.
|
|
*/
|
|
$invalid_token = $token_data;
|
|
$invalid_token->data->customer_id = '';
|
|
$invalid_token = JWT::encode( $invalid_token, 'graphql-woo-cart-session' );
|
|
|
|
$failed = $I->addToCart(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'productId' => $this->product_catalog['t-shirt'],
|
|
'quantity' => 1,
|
|
),
|
|
array( 'woocommerce-session' => "Session {$invalid_token}" )
|
|
);
|
|
|
|
$I->assertArrayHasKey( 'errors', $failed );
|
|
|
|
/**
|
|
* Attempt to remove item from the cart with invalid session token.
|
|
* GraphQL should throw an error and mutation will fail.
|
|
*/
|
|
$invalid_token = $token_data;
|
|
$invalid_token->iss = '';
|
|
$invalid_token = JWT::encode( $invalid_token, 'graphql-woo-cart-session' );
|
|
|
|
$failed = $I->removeItemsFromCart(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'keys' => $cart_item_key,
|
|
),
|
|
array( 'woocommerce-session' => "Session {$invalid_token}" )
|
|
);
|
|
|
|
$I->assertArrayHasKey( 'errors', $failed );
|
|
|
|
/**
|
|
* Attempt to update quantity of item in the cart with invalid session token.
|
|
* GraphQL should throw an error and mutation will fail.
|
|
*/
|
|
$failed = $I->updateItemQuantities(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'items' => array(
|
|
array( 'key' => $cart_item_key, 'quantity' => 0 ),
|
|
),
|
|
),
|
|
array( 'woocommerce-session' => "Session invalid-jwt-token-string" )
|
|
);
|
|
|
|
$I->assertArrayHasKey( 'errors', $failed );
|
|
|
|
/**
|
|
* Attempt to empty cart with invalid session token.
|
|
* GraphQL should throw an error and mutation will fail.
|
|
*/
|
|
$failed = $I->emptyCart(
|
|
array( 'clientMutationId' => 'someId', ),
|
|
array( 'woocommerce-session' => "Session invalid-jwt-token-string" )
|
|
);
|
|
|
|
$I->assertArrayHasKey( 'errors', $failed );
|
|
|
|
/**
|
|
* Attempt to add fee on cart with invalid session token.
|
|
* GraphQL should throw an error and mutation will fail.
|
|
*/
|
|
$failed = $I->addFee(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'name' => 'extra_fee',
|
|
'amount' => 49.99,
|
|
),
|
|
array( 'woocommerce-session' => "Session invalid-jwt-token-string" )
|
|
);
|
|
|
|
$I->assertArrayHasKey( 'errors', $failed );
|
|
|
|
/**
|
|
* Attempt to apply coupon on cart with invalid session token.
|
|
* GraphQL should throw an error and mutation will fail.
|
|
*
|
|
* @Note: No coupons exist in the database, but mutation should fail before that becomes a factor.
|
|
*/
|
|
$failed = $I->applyCoupon(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'code' => 'some_coupon',
|
|
),
|
|
array( 'woocommerce-session' => "Session invalid-jwt-token-string" )
|
|
);
|
|
|
|
$I->assertArrayHasKey( 'errors', $failed );
|
|
|
|
/**
|
|
* Attempt to remove coupon from cart with invalid session token.
|
|
* GraphQL should throw an error and mutation will fail.
|
|
*
|
|
* @Note: No coupons exist on the cart, but mutation should failed before that becomes a factor.
|
|
*/
|
|
$failed = $I->removeCoupons(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'codes' => array( 'some_coupon' ),
|
|
),
|
|
array( 'woocommerce-session' => "Session invalid-jwt-token-string" )
|
|
);
|
|
|
|
$I->assertArrayHasKey( 'errors', $failed );
|
|
|
|
/**
|
|
* Attempt to restore item to the cart with invalid session token.
|
|
* GraphQL should throw an error and mutation will fail.
|
|
*
|
|
* @Note: No items have been removed from the cart in this session,
|
|
* but mutation should failed before that becomes a factor.
|
|
*/
|
|
$failed = $I->restoreCartItems(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'keys' => array( $cart_item_key ),
|
|
),
|
|
array( 'woocommerce-session' => "Session invalid-jwt-token-string" )
|
|
);
|
|
|
|
$I->assertArrayHasKey( 'errors', $failed );
|
|
|
|
/**
|
|
* Attempt to restore item to the cart with invalid session token.
|
|
* GraphQL should throw an error and mutation will fail.
|
|
*
|
|
* @Note: No items have been removed from the cart in this session,
|
|
* but mutation should failed before that becomes a factor.
|
|
*/
|
|
$failed = $I->updateShippingMethod(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'shippingMethods' => array( 'legacy_flat_rate' ),
|
|
),
|
|
array( 'woocommerce-session' => "Session invalid-jwt-token-string" )
|
|
);
|
|
|
|
$I->assertArrayHasKey( 'errors', $failed );
|
|
|
|
/**
|
|
* Attempt to query cart with invalid session token.
|
|
* GraphQL should throw an error and query will fail.
|
|
*/
|
|
$query = '
|
|
query {
|
|
cart {
|
|
contents {
|
|
nodes {
|
|
key
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$failed = $I->sendGraphQLRequest(
|
|
$query,
|
|
null,
|
|
array( 'woocommerce-session' => 'Session invalid-jwt-token-string' )
|
|
);
|
|
|
|
$I->assertArrayHasKey( 'errors', $failed );
|
|
}
|
|
|
|
public function testCartSessionDataMutations( FunctionalTester $I ) {
|
|
/**
|
|
* Add item to the cart
|
|
*/
|
|
$success = $I->addToCart(
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'productId' => $this->product_catalog['socks'],
|
|
'quantity' => 2,
|
|
)
|
|
);
|
|
|
|
$I->assertArrayNotHasKey( 'errors', $success );
|
|
$I->assertArrayHasKey('data', $success );
|
|
$I->assertArrayHasKey('addToCart', $success['data'] );
|
|
$I->assertArrayHasKey('cartItem', $success['data']['addToCart'] );
|
|
$I->assertArrayHasKey('key', $success['data']['addToCart']['cartItem'] );
|
|
$cart_item_key = $success['data']['addToCart']['cartItem']['key'];
|
|
|
|
/**
|
|
* Assert existence and validity of "woocommerce-session" HTTP header.
|
|
*/
|
|
$I->seeHttpHeaderOnce( 'woocommerce-session' );
|
|
$session_token = $I->grabHttpHeader( 'woocommerce-session' );
|
|
|
|
// Decode token
|
|
JWT::$leeway = 60;
|
|
$token_data = ! empty( $session_token )
|
|
? JWT::decode( $session_token, 'graphql-woo-cart-session', array( 'HS256' ) )
|
|
: null;
|
|
|
|
$I->assertNotEmpty( $token_data );
|
|
$I->assertNotEmpty( $token_data->iss );
|
|
$I->assertNotEmpty( $token_data->iat );
|
|
$I->assertNotEmpty( $token_data->nbf );
|
|
$I->assertNotEmpty( $token_data->exp );
|
|
$I->assertNotEmpty( $token_data->data );
|
|
$I->assertNotEmpty( $token_data->data->customer_id );
|
|
|
|
$wp_url = getenv( 'WP_URL' );
|
|
$I->assertEquals( $token_data->iss, $wp_url );
|
|
|
|
/**
|
|
* Set shipping address, so shipping rates can be calculated
|
|
*/
|
|
$input = array(
|
|
'clientMutationId' => 'someId',
|
|
'shipping' => array(
|
|
'state' => 'New York',
|
|
'country' => 'US',
|
|
'postcode' => '12345',
|
|
)
|
|
);
|
|
|
|
$mutation = '
|
|
mutation ( $input: UpdateCustomerInput! ){
|
|
updateCustomer ( input: $input ) {
|
|
customer {
|
|
shipping {
|
|
state
|
|
country
|
|
postcode
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$actual = $I->sendGraphQLRequest( $mutation, $input, array( 'woocommerce-session' => "Session {$session_token}" ) );
|
|
$expected = array(
|
|
'data' => array(
|
|
'updateCustomer' => array(
|
|
'customer' => array(
|
|
'shipping' => array(
|
|
'state' => 'New York',
|
|
'country' => 'US',
|
|
'postcode' => '12345'
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
$I->assertEquals( $expected, $actual );
|
|
|
|
/**
|
|
* Make a cart query request with "woocommerce-session" HTTP Header and confirm
|
|
* correct cart contents and chosen and available shipping methods.
|
|
*/
|
|
$query = '
|
|
query {
|
|
cart {
|
|
contents {
|
|
nodes {
|
|
key
|
|
}
|
|
}
|
|
availableShippingMethods {
|
|
packageDetails
|
|
supportsShippingCalculator
|
|
rates {
|
|
id
|
|
cost
|
|
label
|
|
}
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$actual = $I->sendGraphQLRequest( $query, null, array( 'woocommerce-session' => "Session {$session_token}" ) );
|
|
$expected = array(
|
|
'data' => array(
|
|
'cart' => array(
|
|
'contents' => array(
|
|
'nodes' => array(
|
|
array(
|
|
'key' => $cart_item_key,
|
|
),
|
|
),
|
|
),
|
|
'availableShippingMethods' => array(
|
|
array(
|
|
'packageDetails' => 'socks ×2',
|
|
'supportsShippingCalculator' => true,
|
|
'rates' => array(
|
|
array(
|
|
'id' => 'legacy_flat_rate',
|
|
'cost' => 10.00,
|
|
'label' => 'Flat rate'
|
|
),
|
|
array(
|
|
'id' => 'legacy_free_shipping',
|
|
'cost' => 0,
|
|
'label' => 'Free shipping'
|
|
),
|
|
)
|
|
)
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
$I->assertEquals( $expected, $actual );
|
|
|
|
/**
|
|
* Update shipping method to 'legacy_flat_rate' shipping.
|
|
*/
|
|
$mutation = '
|
|
mutation ($input: UpdateShippingMethodInput!){
|
|
updateShippingMethod(input: $input) {
|
|
cart {
|
|
availableShippingMethods {
|
|
packageDetails
|
|
supportsShippingCalculator
|
|
rates {
|
|
id
|
|
cost
|
|
label
|
|
}
|
|
}
|
|
chosenShippingMethod
|
|
shippingTotal
|
|
shippingTax
|
|
subtotal
|
|
subtotalTax
|
|
total
|
|
}
|
|
}
|
|
}
|
|
';
|
|
|
|
$success = $I->sendGraphQLRequest(
|
|
$mutation,
|
|
array(
|
|
'clientMutationId' => 'someId',
|
|
'shippingMethods' => array( 'legacy_free_shipping' ),
|
|
),
|
|
array( 'woocommerce-session' => "Session {$session_token}" )
|
|
);
|
|
|
|
$I->assertArrayNotHasKey( 'errors', $success );
|
|
$I->assertNotEmpty( $success['data'] );
|
|
$I->assertNotEmpty( $success['data']['updateShippingMethod'] );
|
|
$I->assertNotEmpty( $success['data']['updateShippingMethod']['cart'] );
|
|
$cart = $success['data']['updateShippingMethod']['cart'];
|
|
$I->assertNotEmpty( $cart['availableShippingMethods'] );
|
|
$I->assertEquals( 'legacy_free_shipping', $cart['chosenShippingMethod'] );
|
|
}
|
|
}
|