From b00736ea2350a3c03a107e7f650ad13fc2d3361b Mon Sep 17 00:00:00 2001 From: Daniel Lo Nigro Date: Tue, 3 Mar 2020 16:43:09 -0800 Subject: [PATCH] Allow client-side schema extensions in optimisticResponse Summary: Setting client-side schema extension fields in `optimisticResponse` works fine, but `validateMutation` throws a warning. I've updated `validateMutation` to allow this. My use case is that I have an "is_saving" flag I'm adding to an object using "Client Schema Extensions". I want to set this flag when a mutation is being performed, and unset it when the mutation is complete. I want to display the state of the mutation in several places in the UI, and using local Relay state seemed like an easier way to do that compared to having to pass some React state through several components. Setting this field using `optimisticResponse` works well because Relay will automatically revert the change after the mutation is complete. Reviewed By: bennyhobart Differential Revision: D20228541 fbshipit-source-id: f9ed06739bc0155b29f3da2c28bc727324fc1a16 --- .../__tests__/validateMutation-test.js | 62 +++++++++++++++++++ .../mutations/validateMutation.js | 4 ++ 2 files changed, 66 insertions(+) diff --git a/packages/relay-runtime/mutations/__tests__/validateMutation-test.js b/packages/relay-runtime/mutations/__tests__/validateMutation-test.js index 214263849fee5..014e31ee4642c 100644 --- a/packages/relay-runtime/mutations/__tests__/validateMutation-test.js +++ b/packages/relay-runtime/mutations/__tests__/validateMutation-test.js @@ -553,6 +553,68 @@ describe('validateOptimisticResponse', () => { variables: null, shouldWarn: true, }, + { + name: 'Does not log a warning for client-side schema extensions', + mutation: generateAndCompile( + ` + extend type Feedback { + isSavingLike: Boolean + } + mutation FeedbackLikeMutation( + $input: FeedbackLikeInput + ) { + feedbackLike(input: $input) { + feedback { + doesViewerLike + isSavingLike + } + } + } + `, + ).FeedbackLikeMutation, + optimisticResponse: { + feedbackLike: { + feedback: { + id: 1, + doesViewerLike: true, + isSavingLike: true, + }, + }, + }, + variables: null, + shouldWarn: false, + }, + { + name: 'Logs a warning for invalid client-side schema extension fields', + mutation: generateAndCompile( + ` + extend type Feedback { + isSavingLike: Boolean + } + mutation FeedbackLikeMutation( + $input: FeedbackLikeInput + ) { + feedbackLike(input: $input) { + feedback { + doesViewerLike + isSavingLike + } + } + } + `, + ).FeedbackLikeMutation, + optimisticResponse: { + feedbackLike: { + feedback: { + id: 1, + doesViewerLike: true, + someInvalidField: true, + }, + }, + }, + variables: null, + shouldWarn: true, + }, ].forEach(({name, mutation, optimisticResponse, shouldWarn, variables}) => { it(name, () => { jest.clearAllMocks(); diff --git a/packages/relay-runtime/mutations/validateMutation.js b/packages/relay-runtime/mutations/validateMutation.js index d66e44ed487e6..0ae9f14ab3787 100644 --- a/packages/relay-runtime/mutations/validateMutation.js +++ b/packages/relay-runtime/mutations/validateMutation.js @@ -108,6 +108,10 @@ if (__DEV__) { }); return; case 'ClientExtension': + selection.selections.forEach(subselection => { + validateSelection(optimisticResponse, subselection, context); + }); + return; case 'ModuleImport': case 'LinkedHandle': case 'ScalarHandle':