fix: make name optional in updateProduct mutation (#1014)

* fix: make name optional in updateProduct mutation

The UpdateProductInput inherited name as non_null from CreateProductInput,
requiring callers to always provide a name even when only updating other
fields. Now name is optional for updates — the existing name is preserved
when not provided.

* chore: Linter compliances met
This commit is contained in:
Geoff Taylor
2026-04-02 18:59:48 -04:00
committed by GitHub
parent fc2a0ea56b
commit e361dddff7
3 changed files with 57 additions and 3 deletions
+9 -3
View File
@@ -39,15 +39,21 @@ class Product_Update {
*/
public static function get_input_fields() {
return array_merge(
Product_Create::get_input_fields(),
[
'id' => [
'id' => [
'type' => [ 'non_null' => 'ID' ],
'description' => static function () {
return __( 'Unique identifier for the product.', 'wp-graphql-woocommerce' );
},
],
],
Product_Create::get_input_fields()
'name' => [
'type' => 'String',
'description' => static function () {
return __( 'Name of the product.', 'wp-graphql-woocommerce' );
},
],
]
);
}
+40
View File
@@ -832,4 +832,44 @@ class ProductMutationsTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGrap
$product = wc_get_product( $product_id );
$this->assertFalse( $product );
}
public function testUpdateProductWithoutName() {
$product_id = $this->factory->product->createSimple(
[
'name' => 'Original Name',
'regular_price' => 10,
]
);
$query = '
mutation ( $input: UpdateProductInput! ) {
updateProduct(input: $input) {
product {
databaseId
name
... on ProductWithPricing {
regularPrice(format: RAW)
}
}
}
}
';
$variables = [
'input' => [
'id' => $product_id,
'regularPrice' => 25.00,
],
];
$this->loginAsShopManager();
$response = $this->graphql( compact( 'query', 'variables' ) );
$expected = [
$this->expectedField( 'updateProduct.product.databaseId', $product_id ),
$this->expectedField( 'updateProduct.product.name', 'Original Name' ),
$this->expectedField( 'updateProduct.product.regularPrice', '25' ),
];
$this->assertQuerySuccessful( $response, $expected );
}
}
@@ -246,6 +246,14 @@ class JWK
): string {
$mod = JWT::urlsafeB64Decode($n);
$exp = JWT::urlsafeB64Decode($e);
// Correct encoding for ASN1, as ints are represented as unsigned in jwk
// but signed in ASN1. Prepending null byte makes it unsigned.
if (\strlen($mod) > 0 && \ord($mod[0]) >= 128) {
$mod = \chr(0) . $mod;
}
if (\strlen($exp) > 0 && \ord($exp[0]) >= 128) {
$exp = \chr(0) . $exp;
}
$modulus = \pack('Ca*a*', 2, self::encodeLength(\strlen($mod)), $mod);
$publicExponent = \pack('Ca*a*', 2, self::encodeLength(\strlen($exp)), $exp);