Browse Source

fix(core): Validate OrderLine custom fields in ShopAPI mutations

Fixes #1953
Michael Bromley 3 years ago
parent
commit
d272255112

+ 84 - 0
packages/core/e2e/custom-fields.e2e-spec.ts

@@ -181,6 +181,7 @@ const customConfig = mergeConfig(testConfig(), {
                 readonly: true,
             },
         ],
+        OrderLine: [{ name: 'validateInt', type: 'int', min: 0, max: 10 }],
     } as CustomFields,
 });
 
@@ -687,6 +688,89 @@ describe('Custom fields', () => {
                 }
             `);
         });
+
+        // https://github.com/vendure-ecommerce/vendure/issues/1953
+        describe('validation of OrderLine custom fields', () => {
+            it('addItemToOrder', async () => {
+                try {
+                    const { addItemToOrder } = await shopClient.query(gql`
+                        mutation {
+                            addItemToOrder(
+                                productVariantId: 1
+                                quantity: 1
+                                customFields: { validateInt: 11 }
+                            ) {
+                                ... on Order {
+                                    id
+                                }
+                            }
+                        }
+                    `);
+                    fail('Should have thrown');
+                } catch (e) {
+                    expect(e.message).toContain(
+                        `The custom field 'validateInt' value [11] is greater than the maximum [10]`,
+                    );
+                }
+
+                const { addItemToOrder: result } = await shopClient.query(gql`
+                    mutation {
+                        addItemToOrder(productVariantId: 1, quantity: 1, customFields: { validateInt: 9 }) {
+                            ... on Order {
+                                id
+                                lines {
+                                    customFields {
+                                        validateInt
+                                    }
+                                }
+                            }
+                        }
+                    }
+                `);
+
+                expect(result.lines[0].customFields).toEqual({ validateInt: 9 });
+            });
+
+            it('adjustOrderLine', async () => {
+                try {
+                    const { adjustOrderLine } = await shopClient.query(gql`
+                        mutation {
+                            adjustOrderLine(
+                                orderLineId: "T_1"
+                                quantity: 1
+                                customFields: { validateInt: 11 }
+                            ) {
+                                ... on Order {
+                                    id
+                                }
+                            }
+                        }
+                    `);
+                    fail('Should have thrown');
+                } catch (e) {
+                    expect(e.message).toContain(
+                        `The custom field 'validateInt' value [11] is greater than the maximum [10]`,
+                    );
+                }
+
+                const { adjustOrderLine: result } = await shopClient.query(gql`
+                    mutation {
+                        adjustOrderLine(orderLineId: "T_1", quantity: 1, customFields: { validateInt: 2 }) {
+                            ... on Order {
+                                id
+                                lines {
+                                    customFields {
+                                        validateInt
+                                    }
+                                }
+                            }
+                        }
+                    }
+                `);
+
+                expect(result.lines[0].customFields).toEqual({ validateInt: 2 });
+            });
+        });
     });
 
     describe('public access', () => {

+ 11 - 1
packages/core/src/api/middleware/validate-custom-fields-interceptor.ts

@@ -35,6 +35,7 @@ export class ValidateCustomFieldsInterceptor implements NestInterceptor {
             inputs.add(`Update${entityName}Input`);
             return inputs;
         }, new Set<string>());
+        this.inputsWithCustomFields.add('OrderLineCustomFieldsInput');
     }
 
     async intercept(context: ExecutionContext, next: CallHandler<any>) {
@@ -77,7 +78,16 @@ export class ValidateCustomFieldsInterceptor implements NestInterceptor {
         if (variableValues) {
             const entityName = typeName.replace(/(Create|Update)(.+)Input/, '$2');
             const customFieldConfig = this.configService.customFields[entityName as keyof CustomFields];
-
+            if (typeName === 'OrderLineCustomFieldsInput') {
+                // special case needed to handle custom fields passed via addItemToOrder or adjustOrderLine
+                // mutations.
+                await this.validateCustomFieldsObject(
+                    this.configService.customFields.OrderLine,
+                    languageCode,
+                    variableValues,
+                    injector,
+                );
+            }
             if (variableValues.customFields) {
                 await this.validateCustomFieldsObject(
                     customFieldConfig,