• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wp-graphql / wp-graphql-woocommerce / 23354837106

20 Mar 2026 05:31PM UTC coverage: 83.637% (+0.4%) from 83.244%
23354837106

push

github

web-flow
feat: Product and product attribute mutations (#851)

* devops: Product and product attribute mutation tests generated

* feat: Product Mutations implemented and tested

* chore: Linter and PHPStan compliance met

* fix: resolve test failures in product and variation mutation tests

- Removed duplicate requires for payment-method classes (rebase artifact)
- Wrapped bare `attributes` queries in `... on SimpleProduct` inline
  fragments (attributes field is on ProductWithAttributes interface,
  not the base Product type)
- Fixed attribute label expectations to match factory output (lowercase)
- Fixed relay ID prefix from 'product'/'product_variation' to 'post'
  to match WPGraphQL's actual encoding
- Cache WP_Post before force-deletion and re-cache after so the Product
  model's type resolver can still determine the GraphQL type in the
  response
- Added wp_cache_flush() before asserting product deletion to avoid
  false positives from the re-cached post

* chore: fix PHPCS lint errors in mutation files

* fix: resolve CI test failures for attribute and variation mutations

- Fixed ProductVariation type registration in schema filters so the
  variation mutation output field resolves correctly
- Renamed attribute slug from 'pattern' to 'fabric' in
  ProductAttributeMutationsTest to avoid collision with the pattern
  attribute created by ProductAttributeQueriesTest
- Fixed PHPStan errors for redundant is_wp_error checks
- Updated IntrospectionQueryTest

1251 of 1437 new or added lines in 23 files covered. (87.06%)

13995 of 16733 relevant lines covered (83.64%)

91.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.88
/includes/mutation/class-product-attribute-delete.php
1
<?php
2
/**
3
 * Mutation - deleteProductAttribute
4
 *
5
 * Registers mutation for deleting a product attribute.
6
 *
7
 * @package WPGraphQL\WooCommerce\Mutation
8
 * @since TBD
9
 */
10

11
namespace WPGraphQL\WooCommerce\Mutation;
12

13
use GraphQL\Error\UserError;
14
use GraphQL\Type\Definition\ResolveInfo;
15
use WPGraphQL\AppContext;
16
use WPGraphQL\WooCommerce\Data\Mutation\Product_Mutation;
17

18
/**
19
 * Class Product_Attribute_Delete
20
 */
21
class Product_Attribute_Delete {
22
        /**
23
         * Registers mutation
24
         *
25
         * @return void
26
         */
27
        public static function register_mutation() {
28
                register_graphql_mutation(
182✔
29
                        'deleteProductAttribute',
182✔
30
                        [
182✔
31
                                'inputFields'         => self::get_input_fields(),
182✔
32
                                'outputFields'        => self::get_output_fields(),
182✔
33
                                'mutateAndGetPayload' => self::mutate_and_get_payload(),
182✔
34
                        ]
182✔
35
                );
182✔
36
        }
37

38
        /**
39
         * Defines the mutation input field configuration
40
         *
41
         * @return array
42
         */
43
        public static function get_input_fields() {
44
                return [
182✔
45
                        'id' => [
182✔
46
                                'type'        => [ 'non_null' => 'ID' ],
182✔
47
                                'description' => __( 'Unique identifier for the product.', 'wp-graphql-woocommerce' ),
182✔
48
                        ],
182✔
49
                ];
182✔
50
        }
51

52
        /**
53
         * Defines the mutation output field configuration
54
         *
55
         * @return array
56
         */
57
        public static function get_output_fields() {
58
                return [
182✔
59
                        'attribute' => [
182✔
60
                                'type'    => 'ProductAttributeObject',
182✔
61
                                'resolve' => static function ( $payload ) {
182✔
62
                                        return $payload['attribute'];
1✔
63
                                },
182✔
64
                        ],
182✔
65
                ];
182✔
66
        }
67

68
        /**
69
         * Defines the mutation data modification closure.
70
         *
71
         * @return callable
72
         */
73
        public static function mutate_and_get_payload() {
74
                return static function ( $input, AppContext $context, ResolveInfo $info ) {
182✔
75
                        if ( ! wc_rest_check_manager_permissions( 'attributes', 'delete' ) ) {
1✔
76
                                throw new UserError( __( 'Sorry, you cannot delete attributes.', 'wp-graphql-woocommerce' ) );
1✔
77
                        }
78

79
                        $attribute = Product_Mutation::get_attribute( $input['id'] );
1✔
80
                        $deleted   = wc_delete_attribute( $attribute->attribute_id );
1✔
81

82
                        if ( false === $deleted ) {
1✔
NEW
83
                                throw new UserError( __( 'Failed to delete attribute.', 'wp-graphql-woocommerce' ) );
×
84
                        }
85

86
                        /**
87
                         * Fires after a single attribute is deleted via the REST API.
88
                         *
89
                         * @param object{attribute_id: int} $attribute  The deleted attribute.
90
                         */
91
                        do_action( 'graphql_woocommerce_delete_product_attribute', $attribute );
1✔
92

93
                        return [ 'attribute' => $attribute ];
1✔
94
                };
182✔
95
        }
96
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc