mirror of
https://github.com/wp-graphql/wp-graphql-woocommerce.git
synced 2026-08-14 12:53:44 +02:00
Improve i18n compatibility for WPML, Polylang, and non-latin characters (#994)
* fix: improve i18n compatibility for WPML, Polylang, and non-latin character support - Add Label::get_safe_enum_name() utility with optional transliteration for non-latin tax class/attribute/taxonomy names (#637, #409) - Add "Transliterate non-latin characters" admin setting - Replace get_page_by_path() with WP_Query for product slug resolution so WPML/Polylang can hook into the standard query pipeline (#403, #368) - Split product connections: `products` (toType: Product) and `productsWithVariations` (toType: ProductUnion) so i18n plugins can register language where args on the standard type name (#811, #952) - Add ProductTypesWithVariationsEnum for the ProductUnion connection - Add i18n compatibility tests * chore: Linter compliances met
This commit is contained in:
@@ -122,6 +122,15 @@ class General extends Section {
|
||||
'default' => 'keep_new_fallback_old',
|
||||
'disabled' => defined( 'NO_QL_SESSION_HANDLER' ),
|
||||
],
|
||||
[
|
||||
'name' => 'enable_transliteration',
|
||||
'label' => __( 'Transliterate non-latin characters', 'wp-graphql-woocommerce' ),
|
||||
'desc' => __( 'Converts non-latin characters (Cyrillic, Chinese, Arabic, etc.) to their latin equivalents in GraphQL type and enum names. Enable this if your WooCommerce tax classes, product attributes, or taxonomies use non-latin names. Requires the PHP intl extension.', 'wp-graphql-woocommerce' )
|
||||
. ( ! function_exists( 'transliterator_transliterate' ) ? __( ' <strong>Warning:</strong> The PHP intl extension is not available. This setting will have no effect.', 'wp-graphql-woocommerce' ) : '' ),
|
||||
'type' => 'checkbox',
|
||||
'default' => 'off',
|
||||
'disabled' => ! function_exists( 'transliterator_transliterate' ),
|
||||
],
|
||||
[
|
||||
'name' => 'enable_unsupported_product_type',
|
||||
'label' => __( 'Enable Unsupported types', 'wp-graphql-woocommerce' ),
|
||||
|
||||
@@ -162,6 +162,7 @@ if ( ! class_exists( '\WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce' ) ) :
|
||||
$include_directory_path = get_includes_directory();
|
||||
|
||||
// Include util class files.
|
||||
require $include_directory_path . 'utils/class-label.php';
|
||||
require $include_directory_path . 'utils/class-ql-session-handler.php';
|
||||
require $include_directory_path . 'utils/class-session-transaction-manager.php';
|
||||
|
||||
|
||||
@@ -24,8 +24,23 @@ class Products {
|
||||
* @return void
|
||||
*/
|
||||
public static function register_connections() {
|
||||
// From RootQuery.
|
||||
register_graphql_connection( self::get_connection_config() );
|
||||
// Products connection (toType: Product) — compatible with i18n plugins.
|
||||
register_graphql_connection(
|
||||
self::get_connection_config(
|
||||
[
|
||||
'toType' => 'Product',
|
||||
'fromFieldName' => 'products',
|
||||
'connectionArgs' => self::get_product_connection_args(),
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
// Products with variations connection (toType: ProductUnion).
|
||||
register_graphql_connection(
|
||||
self::get_connection_config(
|
||||
[ 'fromFieldName' => 'productsWithVariations' ]
|
||||
)
|
||||
);
|
||||
|
||||
// From Coupon.
|
||||
register_graphql_connection(
|
||||
@@ -266,7 +281,15 @@ class Products {
|
||||
$to_type = $config['toType'];
|
||||
$from_type = $config['fromType'];
|
||||
if ( 'Product' === $to_type ) {
|
||||
$config['connectionArgs'] = self::get_connection_args();
|
||||
$args = self::get_product_connection_args();
|
||||
$config['connectionArgs'] = ! empty( $config['connectionArgs'] )
|
||||
? array_merge( $config['connectionArgs'], $args )
|
||||
: $args;
|
||||
} elseif ( 'ProductUnion' === $to_type ) {
|
||||
$args = self::get_product_union_connection_args();
|
||||
$config['connectionArgs'] = ! empty( $config['connectionArgs'] )
|
||||
? array_merge( $config['connectionArgs'], $args )
|
||||
: $args;
|
||||
}
|
||||
|
||||
$taxonomies = self::get_product_connected_taxonomies();
|
||||
@@ -333,13 +356,11 @@ class Products {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of where args.
|
||||
*
|
||||
* @param array $extra_args Extra connection args.
|
||||
* Returns the shared base connection args used by both product connections.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_connection_args( $extra_args = [] ): array {
|
||||
private static function get_base_connection_args(): array {
|
||||
$args = [
|
||||
'slugIn' => [
|
||||
'type' => [ 'list_of' => 'String' ],
|
||||
@@ -349,18 +370,6 @@ class Products {
|
||||
'type' => 'String',
|
||||
'description' => __( 'Limit result set to products assigned a specific status.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'type' => [
|
||||
'type' => 'ProductTypesEnum',
|
||||
'description' => __( 'Limit result set to products assigned a specific type.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'typeIn' => [
|
||||
'type' => [ 'list_of' => 'ProductTypesEnum' ],
|
||||
'description' => __( 'Limit result set to products assigned to a group of specific types.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'typeNotIn' => [
|
||||
'type' => [ 'list_of' => 'ProductTypesEnum' ],
|
||||
'description' => __( 'Limit result set to products not assigned to a group of specific types.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'sku' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'wp-graphql-woocommerce' ),
|
||||
@@ -495,10 +504,6 @@ class Products {
|
||||
'type' => 'Boolean',
|
||||
'description' => __( 'Limit result types to types supported by WooGraphQL.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'includeVariations' => [
|
||||
'type' => 'Boolean',
|
||||
'description' => __( 'Include variations in the result set.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'rating' => [
|
||||
'type' => [ 'list_of' => 'Integer' ],
|
||||
'description' => __( 'Limit result set to products with a specific average rating. Must be between 1 and 5', 'wp-graphql-woocommerce' ),
|
||||
@@ -512,6 +517,73 @@ class Products {
|
||||
];
|
||||
}
|
||||
|
||||
return array_merge( get_wc_cpt_connection_args(), $args, $extra_args );
|
||||
return array_merge( get_wc_cpt_connection_args(), $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns connection args for the Product connection (excludes variation types).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_product_connection_args(): array {
|
||||
return array_merge(
|
||||
self::get_base_connection_args(),
|
||||
[
|
||||
'type' => [
|
||||
'type' => 'ProductTypesEnum',
|
||||
'description' => __( 'Limit result set to products assigned a specific type.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'typeIn' => [
|
||||
'type' => [ 'list_of' => 'ProductTypesEnum' ],
|
||||
'description' => __( 'Limit result set to products assigned to a group of specific types.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'typeNotIn' => [
|
||||
'type' => [ 'list_of' => 'ProductTypesEnum' ],
|
||||
'description' => __( 'Limit result set to products not assigned to a group of specific types.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns connection args for the ProductUnion connection (includes variation types).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_product_union_connection_args(): array {
|
||||
return array_merge(
|
||||
self::get_base_connection_args(),
|
||||
[
|
||||
'type' => [
|
||||
'type' => 'ProductTypesWithVariationsEnum',
|
||||
'description' => __( 'Limit result set to products assigned a specific type.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'typeIn' => [
|
||||
'type' => [ 'list_of' => 'ProductTypesWithVariationsEnum' ],
|
||||
'description' => __( 'Limit result set to products assigned to a group of specific types.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'typeNotIn' => [
|
||||
'type' => [ 'list_of' => 'ProductTypesWithVariationsEnum' ],
|
||||
'description' => __( 'Limit result set to products not assigned to a group of specific types.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'includeVariations' => [
|
||||
'type' => 'Boolean',
|
||||
'description' => __( 'Include variations in the result set.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of where args.
|
||||
*
|
||||
* @deprecated Use get_product_connection_args() or get_product_union_connection_args() instead.
|
||||
*
|
||||
* @param array $extra_args Extra connection args.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_connection_args( $extra_args = [] ): array {
|
||||
return array_merge( self::get_product_union_connection_args(), $extra_args );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPEnum;
|
||||
|
||||
use WPGraphQL\Type\WPEnumType;
|
||||
use WPGraphQL\WooCommerce\Utils\Label;
|
||||
|
||||
/**
|
||||
* Class Product_Attribute_Enum
|
||||
@@ -28,7 +28,11 @@ class Product_Attribute_Enum {
|
||||
$tax_object = get_taxonomy( $taxonomy );
|
||||
|
||||
if ( false !== $tax_object && in_array( 'product', $tax_object->object_type, true ) ) {
|
||||
$taxonomy_values[ WPEnumType::get_safe_name( $taxonomy ) ] = [ 'value' => $taxonomy ];
|
||||
$safe_name = Label::get_safe_enum_name( $taxonomy );
|
||||
if ( null === $safe_name ) {
|
||||
continue;
|
||||
}
|
||||
$taxonomy_values[ $safe_name ] = [ 'value' => $taxonomy ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPEnum;
|
||||
|
||||
use WPGraphQL\Type\WPEnumType;
|
||||
use WPGraphQL\WooCommerce\Utils\Label;
|
||||
|
||||
/**
|
||||
* Class Product_Taxonomy
|
||||
@@ -28,7 +28,11 @@ class Product_Taxonomy {
|
||||
$tax_object = get_taxonomy( $taxonomy );
|
||||
|
||||
if ( false !== $tax_object && in_array( 'product', $tax_object->object_type, true ) ) {
|
||||
$taxonomy_values[ WPEnumType::get_safe_name( $taxonomy ) ] = [ 'value' => $taxonomy ];
|
||||
$safe_name = Label::get_safe_enum_name( $taxonomy );
|
||||
if ( null === $safe_name ) {
|
||||
continue;
|
||||
}
|
||||
$taxonomy_values[ $safe_name ] = [ 'value' => $taxonomy ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,5 +59,24 @@ class Product_Types {
|
||||
'values' => $values,
|
||||
]
|
||||
);
|
||||
|
||||
register_graphql_enum_type(
|
||||
'ProductTypesWithVariationsEnum',
|
||||
[
|
||||
'description' => __( 'Product type enumeration including variation types', 'wp-graphql-woocommerce' ),
|
||||
'values' => apply_filters(
|
||||
'graphql_product_types_with_variations_enum_values',
|
||||
array_merge(
|
||||
$values,
|
||||
[
|
||||
'VARIATION' => [
|
||||
'value' => 'variation',
|
||||
'description' => __( 'A product variation', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
]
|
||||
)
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPEnum;
|
||||
|
||||
use WPGraphQL\Type\WPEnumType;
|
||||
use WPGraphQL\WooCommerce\Utils\Label;
|
||||
|
||||
/**
|
||||
* Class Tax_Class
|
||||
@@ -33,7 +33,11 @@ class Tax_Class {
|
||||
|
||||
$classes = \WC_Tax::get_tax_classes();
|
||||
foreach ( $classes as $class ) {
|
||||
$values[ WPEnumType::get_safe_name( $class ) ] = [ 'value' => sanitize_title( $class ) ];
|
||||
$safe_name = Label::get_safe_enum_name( $class );
|
||||
if ( null === $safe_name ) {
|
||||
continue;
|
||||
}
|
||||
$values[ $safe_name ] = [ 'value' => sanitize_title( $class ) ];
|
||||
}
|
||||
|
||||
register_graphql_enum_type(
|
||||
|
||||
@@ -53,8 +53,18 @@ class Product {
|
||||
$product_id = \wc_get_product_id_by_sku( $id );
|
||||
break;
|
||||
case 'slug':
|
||||
$post = get_page_by_path( $id, OBJECT, 'product' );
|
||||
$product_id = ! empty( $post ) ? absint( $post->ID ) : 0;
|
||||
$query = new \WP_Query(
|
||||
[
|
||||
'name' => $id,
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => 1,
|
||||
'fields' => 'ids',
|
||||
]
|
||||
);
|
||||
/** @var int $post_id */
|
||||
$post_id = ! empty( $query->posts ) ? $query->posts[0] : 0;
|
||||
$product_id = absint( $post_id );
|
||||
break;
|
||||
case 'database_id':
|
||||
$product_id = absint( $id );
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Label utility functions for GraphQL name formatting.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Utils
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Utils;
|
||||
|
||||
use WPGraphQL\Type\WPEnumType;
|
||||
|
||||
/**
|
||||
* Class Label
|
||||
*/
|
||||
class Label {
|
||||
/**
|
||||
* Returns a safe GraphQL enum name for the given value, optionally
|
||||
* transliterating non-latin characters when the setting is enabled.
|
||||
*
|
||||
* Falls back to WPEnumType::get_safe_name() and returns null when
|
||||
* the result contains no alphanumeric characters (i.e. is meaningless).
|
||||
*
|
||||
* @param string $value The raw value to convert to a safe enum name.
|
||||
*
|
||||
* @return string|null The safe name, or null if the value cannot produce a valid GraphQL name.
|
||||
*/
|
||||
public static function get_safe_enum_name( string $value ): ?string {
|
||||
if (
|
||||
'on' === woographql_setting( 'enable_transliteration', 'off' )
|
||||
&& function_exists( 'transliterator_transliterate' )
|
||||
&& preg_match( '/[^\x20-\x7E]/', $value )
|
||||
) {
|
||||
$value = transliterator_transliterate( 'Any-Latin; Latin-ASCII', $value );
|
||||
}
|
||||
|
||||
if ( empty( $value ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$safe_name = WPEnumType::get_safe_name( $value );
|
||||
|
||||
if ( ! preg_match( '/[A-Za-z0-9]/', $safe_name ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $safe_name;
|
||||
}
|
||||
}
|
||||
@@ -263,7 +263,7 @@ class ConnectionPaginationTest extends \Tests\WPGraphQL\WooCommerce\TestCase\Woo
|
||||
);
|
||||
|
||||
$query = '
|
||||
query ($first: Int, $last: Int, $after: String, $before: String, $where: RootQueryToProductUnionConnectionWhereArgs) {
|
||||
query ($first: Int, $last: Int, $after: String, $before: String, $where: RootQueryToProductConnectionWhereArgs) {
|
||||
products(first: $first, last: $last, after: $after, before: $before, where: $where) {
|
||||
found
|
||||
nodes {
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tests for internationalization (i18n) compatibility.
|
||||
*
|
||||
* @see https://github.com/wp-graphql/wp-graphql-woocommerce/issues/637
|
||||
* @see https://github.com/wp-graphql/wp-graphql-woocommerce/issues/409
|
||||
* @see https://github.com/wp-graphql/wp-graphql-woocommerce/issues/403
|
||||
*/
|
||||
class I18nCompatibilityTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
|
||||
/**
|
||||
* Test that non-latin tax class names do not break schema introspection
|
||||
* when transliteration is disabled.
|
||||
*
|
||||
* @see https://github.com/wp-graphql/wp-graphql-woocommerce/issues/637
|
||||
*/
|
||||
public function testNonLatinTaxClassDoesNotBreakSchemaWhenTransliterationDisabled() {
|
||||
// Ensure transliteration is disabled.
|
||||
$existing = get_option( 'woographql_settings', [] );
|
||||
update_option(
|
||||
'woographql_settings',
|
||||
array_merge( is_array( $existing ) ? $existing : [], [ 'enable_transliteration' => 'off' ] )
|
||||
);
|
||||
|
||||
// Create tax classes with non-latin characters.
|
||||
\WC_Tax::create_tax_class( 'Сниженная ставка', 'reduced-cyrillic' );
|
||||
\WC_Tax::create_tax_class( '减税率', 'chinese-rate' );
|
||||
\WC_Tax::create_tax_class( 'Valid Rate', 'valid-rate' );
|
||||
|
||||
$this->clearSchema();
|
||||
|
||||
// Run an introspection query — this should not throw a 500 error.
|
||||
$query = '{
|
||||
__schema {
|
||||
types {
|
||||
name
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$this->assertQuerySuccessful(
|
||||
$response,
|
||||
[ $this->expectedField( '__schema.types', static::NOT_FALSY ) ]
|
||||
);
|
||||
|
||||
// Query the TaxClassEnum values.
|
||||
$query = '{
|
||||
__type(name: "TaxClassEnum") {
|
||||
enumValues {
|
||||
name
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$enum_values = $this->lodashGet( $response, 'data.__type.enumValues' );
|
||||
$enum_names = array_column( $enum_values, 'name' );
|
||||
|
||||
// Non-latin names produce underscore-only values when transliteration is off.
|
||||
// These should be skipped to avoid collisions and meaningless enum entries.
|
||||
$this->assertNotContains( '_', $enum_names, 'Underscore-only enum values should be skipped.' );
|
||||
|
||||
// The valid latin class should still be present.
|
||||
$this->assertContains( 'VALID_RATE', $enum_names, 'Valid latin tax class should be in the enum.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that enabling transliteration converts non-latin tax class names
|
||||
* into valid, meaningful GraphQL enum values.
|
||||
*
|
||||
* @see https://github.com/wp-graphql/wp-graphql-woocommerce/issues/637
|
||||
*/
|
||||
public function testNonLatinTaxClassTransliteratedWhenEnabled() {
|
||||
if ( ! function_exists( 'transliterator_transliterate' ) ) {
|
||||
$this->markTestSkipped( 'intl extension not available.' );
|
||||
}
|
||||
|
||||
// Enable transliteration setting.
|
||||
$existing = get_option( 'woographql_settings', [] );
|
||||
update_option(
|
||||
'woographql_settings',
|
||||
array_merge( is_array( $existing ) ? $existing : [], [ 'enable_transliteration' => 'on' ] )
|
||||
);
|
||||
|
||||
// Create tax classes with non-latin names.
|
||||
\WC_Tax::create_tax_class( 'Ставка НДС', 'nds-rate' );
|
||||
\WC_Tax::create_tax_class( '减税率', 'chinese-rate' );
|
||||
\WC_Tax::create_tax_class( 'Valid Rate', 'valid-rate' );
|
||||
|
||||
$this->clearSchema();
|
||||
|
||||
// Query the TaxClassEnum values via introspection.
|
||||
$query = '{
|
||||
__type(name: "TaxClassEnum") {
|
||||
enumValues {
|
||||
name
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$this->assertQuerySuccessful(
|
||||
$response,
|
||||
[ $this->expectedField( '__type.enumValues', static::NOT_FALSY ) ]
|
||||
);
|
||||
|
||||
$enum_values = $this->lodashGet( $response, 'data.__type.enumValues' );
|
||||
$enum_names = array_column( $enum_values, 'name' );
|
||||
|
||||
// Non-latin classes should be transliterated, not produce underscore-only names.
|
||||
$this->assertNotContains( '_', $enum_names, 'Transliterated enum values should not be underscore-only.' );
|
||||
|
||||
// Verify all enum values have at least one alphanumeric character.
|
||||
foreach ( $enum_values as $value ) {
|
||||
$this->assertMatchesRegularExpression(
|
||||
'/[A-Za-z0-9]/',
|
||||
$value['name'],
|
||||
sprintf( 'Enum value "%s" must contain at least one alphanumeric character.', $value['name'] )
|
||||
);
|
||||
}
|
||||
|
||||
// The Cyrillic class should be transliterated.
|
||||
$this->assertContains( 'STAVKA_NDS', $enum_names, 'Cyrillic tax class should be transliterated.' );
|
||||
|
||||
// The Chinese class should be transliterated.
|
||||
$this->assertContains( 'JIAN_SHUI_LU', $enum_names, 'Chinese tax class should be transliterated.' );
|
||||
|
||||
// The valid latin class should still be present.
|
||||
$this->assertContains( 'VALID_RATE', $enum_names, 'Valid latin tax class should be in the enum.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that product slug resolution uses WordPress's standard query mechanisms
|
||||
* which i18n plugins (WPML, Polylang) can hook into.
|
||||
*
|
||||
* @see https://github.com/wp-graphql/wp-graphql-woocommerce/issues/403
|
||||
*/
|
||||
public function testProductSlugResolutionUsesNodeResolver() {
|
||||
$product_id = $this->factory->product->createSimple();
|
||||
$slug = get_post_field( 'post_name', $product_id );
|
||||
|
||||
$query = '
|
||||
query ($slug: ID!) {
|
||||
product(id: $slug, idType: SLUG) {
|
||||
... on SimpleProduct {
|
||||
databaseId
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
';
|
||||
|
||||
$response = $this->graphql(
|
||||
[
|
||||
'query' => $query,
|
||||
'variables' => [ 'slug' => $slug ],
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertQuerySuccessful(
|
||||
$response,
|
||||
[
|
||||
$this->expectedField( 'product.databaseId', $product_id ),
|
||||
$this->expectedField( 'product.slug', $slug ),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1075,7 +1075,7 @@ class ProductQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQ
|
||||
|
||||
// Create query.
|
||||
$query = '
|
||||
query( $where: RootQueryToProductUnionConnectionWhereArgs ) {
|
||||
query( $where: RootQueryToProductConnectionWhereArgs ) {
|
||||
products( where: $where ) {
|
||||
nodes {
|
||||
... on SimpleProduct {
|
||||
|
||||
@@ -283,8 +283,8 @@ class ProductVariationQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\
|
||||
);
|
||||
|
||||
$query = '
|
||||
query ( $type: ProductTypesEnum, $typeIn: [ProductTypesEnum], $includeVariations: Boolean ) {
|
||||
products( where: { type: $type, typeIn: $typeIn includeVariations: $includeVariations } ) {
|
||||
query ( $type: ProductTypesWithVariationsEnum, $typeIn: [ProductTypesWithVariationsEnum], $includeVariations: Boolean ) {
|
||||
productsWithVariations( where: { type: $type, typeIn: $typeIn includeVariations: $includeVariations } ) {
|
||||
nodes {
|
||||
id
|
||||
}
|
||||
@@ -297,9 +297,9 @@ class ProductVariationQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\
|
||||
*/
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$expected = [
|
||||
$this->expectedField( 'products.nodes.0.id', $this->toRelayId( 'post', $product_id ) ),
|
||||
$this->not()->expectedField( 'products.nodes.#.id', $this->toRelayId( 'post', $variation_id ) ),
|
||||
$this->not()->expectedField( 'products.nodes.#.id', $this->toRelayId( 'post', $other_variation_id ) ),
|
||||
$this->expectedField( 'productsWithVariations.nodes.0.id', $this->toRelayId( 'post', $product_id ) ),
|
||||
$this->not()->expectedField( 'productsWithVariations.nodes.#.id', $this->toRelayId( 'post', $variation_id ) ),
|
||||
$this->not()->expectedField( 'productsWithVariations.nodes.#.id', $this->toRelayId( 'post', $other_variation_id ) ),
|
||||
];
|
||||
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
@@ -310,22 +310,22 @@ class ProductVariationQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\
|
||||
$variables = [ 'type' => 'VARIATION' ];
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->not()->expectedField( 'products.nodes.#.id', $this->toRelayId( 'post', $product_id ) ),
|
||||
$this->expectedField( 'products.nodes.#.id', $this->toRelayId( 'post', $variation_id ) ),
|
||||
$this->expectedField( 'products.nodes.#.id', $this->toRelayId( 'post', $other_variation_id ) ),
|
||||
$this->not()->expectedField( 'productsWithVariations.nodes.#.id', $this->toRelayId( 'post', $product_id ) ),
|
||||
$this->expectedField( 'productsWithVariations.nodes.#.id', $this->toRelayId( 'post', $variation_id ) ),
|
||||
$this->expectedField( 'productsWithVariations.nodes.#.id', $this->toRelayId( 'post', $other_variation_id ) ),
|
||||
];
|
||||
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
|
||||
/**
|
||||
* Assert result with "typeIn" set to "VARIATION" & "VARIATION" products and variations are returned.
|
||||
* Assert result with "includeVariations" returns products and variations.
|
||||
*/
|
||||
$variables = [ 'includeVariations' => true ];
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedField( 'products.nodes.#.id', $this->toRelayId( 'post', $product_id ) ),
|
||||
$this->expectedField( 'products.nodes.#.id', $this->toRelayId( 'post', $variation_id ) ),
|
||||
$this->expectedField( 'products.nodes.#.id', $this->toRelayId( 'post', $other_variation_id ) ),
|
||||
$this->expectedField( 'productsWithVariations.nodes.#.id', $this->toRelayId( 'post', $product_id ) ),
|
||||
$this->expectedField( 'productsWithVariations.nodes.#.id', $this->toRelayId( 'post', $variation_id ) ),
|
||||
$this->expectedField( 'productsWithVariations.nodes.#.id', $this->toRelayId( 'post', $other_variation_id ) ),
|
||||
];
|
||||
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
|
||||
Reference in New Issue
Block a user