From e596faac720d127baea60f84ee2c9b286ffbc72d Mon Sep 17 00:00:00 2001 From: Iha Shin Date: Tue, 10 Dec 2024 17:26:47 -0800 Subject: [PATCH] Add more tests --- ...eFragmentTestListUpdateFragment.graphql.js | 61 ++++++++ ...erveFragmentTestListUpdateQuery.graphql.js | 137 ++++++++++++++++++ ...ragmentDataTestOkPluralFragment.graphql.js | 61 ++++++++ ...orFragmentDataTestOkPluralQuery.graphql.js | 137 ++++++++++++++++++ .../store/__tests__/observeFragment-test.js | 49 +++++++ .../__tests__/waitForFragmentData-test.js | 33 +++++ 6 files changed, 478 insertions(+) create mode 100644 packages/relay-runtime/store/__tests__/__generated__/observeFragmentTestListUpdateFragment.graphql.js create mode 100644 packages/relay-runtime/store/__tests__/__generated__/observeFragmentTestListUpdateQuery.graphql.js create mode 100644 packages/relay-runtime/store/__tests__/__generated__/waitForFragmentDataTestOkPluralFragment.graphql.js create mode 100644 packages/relay-runtime/store/__tests__/__generated__/waitForFragmentDataTestOkPluralQuery.graphql.js diff --git a/packages/relay-runtime/store/__tests__/__generated__/observeFragmentTestListUpdateFragment.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/observeFragmentTestListUpdateFragment.graphql.js new file mode 100644 index 000000000000..dd62e819b969 --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/observeFragmentTestListUpdateFragment.graphql.js @@ -0,0 +1,61 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @oncall relay + * + * @generated SignedSource<> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { Fragment, ReaderFragment } from 'relay-runtime'; +import type { FragmentType } from "relay-runtime"; +declare export opaque type observeFragmentTestListUpdateFragment$fragmentType: FragmentType; +export type observeFragmentTestListUpdateFragment$data = $ReadOnlyArray<{| + +name: ?string, + +$fragmentType: observeFragmentTestListUpdateFragment$fragmentType, +|}>; +export type observeFragmentTestListUpdateFragment$key = $ReadOnlyArray<{ + +$data?: observeFragmentTestListUpdateFragment$data, + +$fragmentSpreads: observeFragmentTestListUpdateFragment$fragmentType, + ... +}>; +*/ + +var node/*: ReaderFragment*/ = { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": { + "plural": true + }, + "name": "observeFragmentTestListUpdateFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } + ], + "type": "User", + "abstractKey": null +}; + +if (__DEV__) { + (node/*: any*/).hash = "30d272ba4e5c5a9eb1d9a79015a69ec3"; +} + +module.exports = ((node/*: any*/)/*: Fragment< + observeFragmentTestListUpdateFragment$fragmentType, + observeFragmentTestListUpdateFragment$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/__generated__/observeFragmentTestListUpdateQuery.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/observeFragmentTestListUpdateQuery.graphql.js new file mode 100644 index 000000000000..70cac22b20f6 --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/observeFragmentTestListUpdateQuery.graphql.js @@ -0,0 +1,137 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @oncall relay + * + * @generated SignedSource<<4337e2999734809a390206fb499f653e>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { ConcreteRequest, Query } from 'relay-runtime'; +import type { observeFragmentTestListUpdateFragment$fragmentType } from "./observeFragmentTestListUpdateFragment.graphql"; +export type observeFragmentTestListUpdateQuery$variables = {||}; +export type observeFragmentTestListUpdateQuery$data = {| + +nodes: ?$ReadOnlyArray, +|}; +export type observeFragmentTestListUpdateQuery = {| + response: observeFragmentTestListUpdateQuery$data, + variables: observeFragmentTestListUpdateQuery$variables, +|}; +*/ + +var node/*: ConcreteRequest*/ = (function(){ +var v0 = [ + { + "kind": "Literal", + "name": "ids", + "value": [ + "1", + "2" + ] + } +]; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "observeFragmentTestListUpdateQuery", + "selections": [ + { + "alias": null, + "args": (v0/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "nodes", + "plural": true, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "observeFragmentTestListUpdateFragment" + } + ], + "storageKey": "nodes(ids:[\"1\",\"2\"])" + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "observeFragmentTestListUpdateQuery", + "selections": [ + { + "alias": null, + "args": (v0/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "nodes", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, + { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } + ], + "type": "User", + "abstractKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } + ], + "storageKey": "nodes(ids:[\"1\",\"2\"])" + } + ] + }, + "params": { + "cacheID": "17a222c7e13bc4a3b9c0c108377514da", + "id": null, + "metadata": {}, + "name": "observeFragmentTestListUpdateQuery", + "operationKind": "query", + "text": "query observeFragmentTestListUpdateQuery {\n nodes(ids: [\"1\", \"2\"]) {\n __typename\n ...observeFragmentTestListUpdateFragment\n id\n }\n}\n\nfragment observeFragmentTestListUpdateFragment on User {\n name\n}\n" + } +}; +})(); + +if (__DEV__) { + (node/*: any*/).hash = "493ccdbc127bfccc347fc16107f21b79"; +} + +module.exports = ((node/*: any*/)/*: Query< + observeFragmentTestListUpdateQuery$variables, + observeFragmentTestListUpdateQuery$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/__generated__/waitForFragmentDataTestOkPluralFragment.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/waitForFragmentDataTestOkPluralFragment.graphql.js new file mode 100644 index 000000000000..ecd0f3164f63 --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/waitForFragmentDataTestOkPluralFragment.graphql.js @@ -0,0 +1,61 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @oncall relay + * + * @generated SignedSource<<2ed8051023394e48547a26c640b8e13c>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { Fragment, ReaderFragment } from 'relay-runtime'; +import type { FragmentType } from "relay-runtime"; +declare export opaque type waitForFragmentDataTestOkPluralFragment$fragmentType: FragmentType; +export type waitForFragmentDataTestOkPluralFragment$data = $ReadOnlyArray<{| + +name: ?string, + +$fragmentType: waitForFragmentDataTestOkPluralFragment$fragmentType, +|}>; +export type waitForFragmentDataTestOkPluralFragment$key = $ReadOnlyArray<{ + +$data?: waitForFragmentDataTestOkPluralFragment$data, + +$fragmentSpreads: waitForFragmentDataTestOkPluralFragment$fragmentType, + ... +}>; +*/ + +var node/*: ReaderFragment*/ = { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": { + "plural": true + }, + "name": "waitForFragmentDataTestOkPluralFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } + ], + "type": "User", + "abstractKey": null +}; + +if (__DEV__) { + (node/*: any*/).hash = "27b1b1a834949ad358eaf6d1396d3f9d"; +} + +module.exports = ((node/*: any*/)/*: Fragment< + waitForFragmentDataTestOkPluralFragment$fragmentType, + waitForFragmentDataTestOkPluralFragment$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/__generated__/waitForFragmentDataTestOkPluralQuery.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/waitForFragmentDataTestOkPluralQuery.graphql.js new file mode 100644 index 000000000000..c1f1dc35eef4 --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/waitForFragmentDataTestOkPluralQuery.graphql.js @@ -0,0 +1,137 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @oncall relay + * + * @generated SignedSource<<5eca2a10e99142f6f4e5d99b02421ad1>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { ConcreteRequest, Query } from 'relay-runtime'; +import type { waitForFragmentDataTestOkPluralFragment$fragmentType } from "./waitForFragmentDataTestOkPluralFragment.graphql"; +export type waitForFragmentDataTestOkPluralQuery$variables = {||}; +export type waitForFragmentDataTestOkPluralQuery$data = {| + +nodes: ?$ReadOnlyArray, +|}; +export type waitForFragmentDataTestOkPluralQuery = {| + response: waitForFragmentDataTestOkPluralQuery$data, + variables: waitForFragmentDataTestOkPluralQuery$variables, +|}; +*/ + +var node/*: ConcreteRequest*/ = (function(){ +var v0 = [ + { + "kind": "Literal", + "name": "ids", + "value": [ + "1", + "2" + ] + } +]; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "waitForFragmentDataTestOkPluralQuery", + "selections": [ + { + "alias": null, + "args": (v0/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "nodes", + "plural": true, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "waitForFragmentDataTestOkPluralFragment" + } + ], + "storageKey": "nodes(ids:[\"1\",\"2\"])" + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "waitForFragmentDataTestOkPluralQuery", + "selections": [ + { + "alias": null, + "args": (v0/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "nodes", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, + { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } + ], + "type": "User", + "abstractKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } + ], + "storageKey": "nodes(ids:[\"1\",\"2\"])" + } + ] + }, + "params": { + "cacheID": "91c66e0b45b06f9cc7a66477f8156418", + "id": null, + "metadata": {}, + "name": "waitForFragmentDataTestOkPluralQuery", + "operationKind": "query", + "text": "query waitForFragmentDataTestOkPluralQuery {\n nodes(ids: [\"1\", \"2\"]) {\n __typename\n ...waitForFragmentDataTestOkPluralFragment\n id\n }\n}\n\nfragment waitForFragmentDataTestOkPluralFragment on User {\n name\n}\n" + } +}; +})(); + +if (__DEV__) { + (node/*: any*/).hash = "139b32cebe816906461147bcb6b1db45"; +} + +module.exports = ((node/*: any*/)/*: Query< + waitForFragmentDataTestOkPluralQuery$variables, + waitForFragmentDataTestOkPluralQuery$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/observeFragment-test.js b/packages/relay-runtime/store/__tests__/observeFragment-test.js index 909f1847e38b..8d0e2874d254 100644 --- a/packages/relay-runtime/store/__tests__/observeFragment-test.js +++ b/packages/relay-runtime/store/__tests__/observeFragment-test.js @@ -520,6 +520,55 @@ test('Resolver error with @relay(plural: true) @throwOnFieldError', async () => }); }); +test('Store update across list items notifies multiple times', async () => { + const query = graphql` + query observeFragmentTestListUpdateQuery { + nodes(ids: ["1", "2"]) { + ...observeFragmentTestListUpdateFragment + } + } + `; + + const fragment = graphql` + fragment observeFragmentTestListUpdateFragment on User + @relay(plural: true) { + name + } + `; + + const environment = createMockEnvironment({ + store: new LiveResolverStore(new RelayRecordSource()), + }); + const variables = {}; + const operation = createOperationDescriptor(query, variables); + environment.commitPayload(operation, { + nodes: [ + {id: '1', __typename: 'User', name: 'Alice'}, + {id: '2', __typename: 'User', name: 'Bob'}, + ], + }); + const {data} = environment.lookup(operation.fragment); + // $FlowFixMe Data is untyped + const observable = observeFragment(environment, fragment, data.nodes); + withObservableValues(observable, results => { + expect(results).toEqual([ + {state: 'ok', value: [{name: 'Alice'}, {name: 'Bob'}]}, + ]); + + environment.commitPayload(operation, { + nodes: [ + {id: '1', __typename: 'User', name: 'Alice updated'}, + {id: '2', __typename: 'User', name: 'Bob updated'}, + ], + }); + expect(results).toEqual([ + {state: 'ok', value: [{name: 'Alice'}, {name: 'Bob'}]}, + {state: 'ok', value: [{name: 'Alice updated'}, {name: 'Bob'}]}, + {state: 'ok', value: [{name: 'Alice updated'}, {name: 'Bob updated'}]}, + ]); + }); +}); + test('data goes missing due to unrelated query response', async () => { const query = graphql` query observeFragmentTestMissingDataQuery { diff --git a/packages/relay-runtime/store/__tests__/waitForFragmentData-test.js b/packages/relay-runtime/store/__tests__/waitForFragmentData-test.js index ec64390dd1a9..b2cb899a5d28 100644 --- a/packages/relay-runtime/store/__tests__/waitForFragmentData-test.js +++ b/packages/relay-runtime/store/__tests__/waitForFragmentData-test.js @@ -52,6 +52,39 @@ test('data ok', async () => { expect(result).toEqual({name: 'Elizabeth'}); }); +test('data ok with plural fragment', async () => { + const query = graphql` + query waitForFragmentDataTestOkPluralQuery { + nodes(ids: ["1", "2"]) { + ...waitForFragmentDataTestOkPluralFragment + } + } + `; + + const fragment = graphql` + fragment waitForFragmentDataTestOkPluralFragment on User + @relay(plural: true) { + name + } + `; + + const environment = createMockEnvironment({ + store: new LiveResolverStore(new RelayRecordSource()), + }); + const variables = {}; + const operation = createOperationDescriptor(query, variables); + environment.commitPayload(operation, { + nodes: [ + {id: '1', __typename: 'User', name: 'Alice'}, + {id: '2', __typename: 'User', name: 'Bob'}, + ], + }); + const {data} = environment.lookup(operation.fragment); + // $FlowFixMe - data is untyped + const result = await waitForFragmentData(environment, fragment, data.nodes); + expect(result).toEqual([{name: 'Alice'}, {name: 'Bob'}]); +}); + test('Promise rejects with @throwOnFieldError', async () => { const query = graphql` query waitForFragmentDataTestThrowOnFieldErrorQuery {