Skip to content

Commit 47d676d

Browse files
alunyovfacebook-github-bot
authored andcommitted
Generate payload for operation
Reviewed By: jstejada Differential Revision: D14406786 fbshipit-source-id: 929fc242a4127e368fa6785cd12585d92550cd2a
1 parent fdff791 commit 47d676d

File tree

3 files changed

+112
-15
lines changed

3 files changed

+112
-15
lines changed

packages/relay-test-utils/RelayMockPayloadGenerator.js

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ import type {
4747
ReaderSelection,
4848
ReaderScalarField,
4949
ReaderLinkedField,
50+
NormalizationOperation,
5051
NormalizationSelection,
5152
NormalizationLinkedField,
5253
NormalizationScalarField,
54+
OperationDescriptor,
5355
} from 'relay-runtime';
5456

5557
type ValueResolver = (
@@ -88,7 +90,11 @@ function createIdGenerator() {
8890

8991
const DEFAULT_MOCK_RESOLVERS = {
9092
ID(context, generateId: () => number) {
91-
return `<${context.parentType}-mock-id-${generateId()}>`;
93+
return `<${
94+
context.parentType != null && context.parentType !== DEFAULT_MOCK_TYPENAME
95+
? context.parentType + '-'
96+
: ''
97+
}mock-id-${generateId()}>`;
9298
},
9399
Boolean() {
94100
return false;
@@ -177,7 +183,7 @@ class RelayMockPayloadGenerator {
177183
selections: $ReadOnlyArray<ReaderSelection | NormalizationSelection>,
178184
typeName: string,
179185
plural: boolean,
180-
): mixed {
186+
): MockData | $ReadOnlyArray<MockData> {
181187
const generateListItem = () => {
182188
const defaultValues = this._getDefaultValuesForObject(
183189
typeName,
@@ -207,7 +213,7 @@ class RelayMockPayloadGenerator {
207213
path: $ReadOnlyArray<string>,
208214
prevData: ?MockData,
209215
defaultValues: ?MockData,
210-
): MockData | $ReadOnlyArray<MockData> {
216+
): MockData {
211217
const {selections, typeName} = traversable;
212218

213219
return this._traverseSelections(
@@ -588,11 +594,11 @@ class RelayMockPayloadGenerator {
588594
* Generate mock variables for ReaderFragment
589595
*/
590596
function generateVariables(
591-
fragment: ReaderFragment,
597+
node: ReaderFragment | NormalizationOperation,
592598
mockResolvers: ?MockResolvers,
593599
): Variables {
594600
const variables = {};
595-
const {argumentDefinitions} = fragment;
601+
const {argumentDefinitions} = node;
596602
const argumentValueGenerator = createValueResolver({
597603
...DEFAULT_MOCK_RESOLVERS,
598604
...mockResolvers,
@@ -625,20 +631,46 @@ function generateVariables(
625631
* Generate mock data for ReaderFragment selection
626632
*/
627633
function generateData(
628-
fragment: ReaderFragment,
634+
node: ReaderFragment | NormalizationOperation,
629635
mockResolvers: ?MockResolvers,
630-
variables?: Variables = generateVariables(fragment, mockResolvers),
636+
variables?: Variables = generateVariables(node, mockResolvers),
631637
schema?: ?GraphQLSchema,
632-
): mixed {
638+
): MockData | $ReadOnlyArray<MockData> {
633639
const mockGenerator = new RelayMockPayloadGenerator({
634640
variables,
635641
schema,
636642
mockResolvers,
637643
});
638-
const data = mockGenerator.generate(
639-
fragment.selections,
640-
fragment.type,
641-
fragment.metadata?.plural ?? false,
644+
let typeName;
645+
if (node.kind === 'Operation') {
646+
if (node.name.endsWith('Mutation')) {
647+
typeName = 'Mutation';
648+
} else if (node.name.endsWith('Subscription')) {
649+
typeName = 'Subscription';
650+
} else {
651+
typeName = 'Query';
652+
}
653+
} else {
654+
typeName = node.type;
655+
}
656+
const plural =
657+
node.kind === 'Operation' ? false : node.metadata?.plural ?? false;
658+
const data = mockGenerator.generate(node.selections, typeName, plural);
659+
return data;
660+
}
661+
662+
function generateDataForOperation(
663+
operation: OperationDescriptor,
664+
mockResolvers: ?MockResolvers,
665+
): MockData {
666+
const data = generateData(
667+
operation.node.operation,
668+
mockResolvers,
669+
operation.variables,
670+
);
671+
invariant(
672+
!Array.isArray(data),
673+
'RelayMockPayloadGenerator: Invalid generated payload, unexpected array.',
642674
);
643675
return data;
644676
}
@@ -647,4 +679,5 @@ module.exports = {
647679
DEFAULT_MOCK_TYPENAME,
648680
generateVariables,
649681
generateData,
682+
generateDataForOperation,
650683
};

packages/relay-test-utils/__tests__/RelayMockPayloadGenerator-test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const RelayTestSchema = require('../RelayTestSchema');
1717
// $FlowFixMe
1818
const {FIXTURE_TAG, generateAndCompile} = require('../RelayModernTestUtils');
1919
const {parse, print} = require('graphql');
20+
const {getRequest, createOperationDescriptor} = require('relay-runtime');
2021

2122
import type {MockResolvers} from '../RelayMockPayloadGenerator';
2223

@@ -619,3 +620,34 @@ test('should return `null` for selection if that is specified in default values'
619620
},
620621
);
621622
});
623+
624+
test('generate payload for operation', () => {
625+
const graphql = `
626+
query TestQuery($id: ID!, $scale: Float) {
627+
node(id: $id) {
628+
... on User {
629+
name
630+
profile_picture(scale: $scale) {
631+
uri
632+
}
633+
}
634+
}
635+
}
636+
`;
637+
const {TestQuery: query} = compile(graphql);
638+
const variables = RelayMockPayloadGenerator.generateVariables(query.fragment);
639+
const operation = createOperationDescriptor(getRequest(query), variables);
640+
const data = RelayMockPayloadGenerator.generateDataForOperation(operation);
641+
expect({
642+
[FIXTURE_TAG]: true,
643+
input: print(parse(graphql)),
644+
output: JSON.stringify(
645+
{
646+
variables,
647+
data,
648+
},
649+
null,
650+
2,
651+
),
652+
}).toMatchSnapshot();
653+
});

packages/relay-test-utils/__tests__/__snapshots__/RelayMockPayloadGenerator-test.js.snap

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ fragment TestFragment on User {
132132
},
133133
"actor": {
134134
"name": "<mock-value-for-field-\\"name\\">",
135-
"id": "<__MockObject-mock-id-1>",
135+
"id": "<mock-id-1>",
136136
"__typename": "__MockObject"
137137
},
138138
"myActor": {
@@ -304,7 +304,7 @@ fragment TestFragment on User @argumentDefinitions(condition: {type: "Boolean!"}
304304
"id": "<User-mock-id-1>",
305305
"name": "<mock-value-for-field-\\"name\\">",
306306
"myActor": {
307-
"id": "<__MockObject-mock-id-2>",
307+
"id": "<mock-id-2>",
308308
"name": "<mock-value-for-field-\\"name\\">"
309309
},
310310
"customName": "<mock-value-for-field-\\"customName\\">",
@@ -452,7 +452,7 @@ Output: {
452452
"variables": {},
453453
"payload": {
454454
"actor": {
455-
"id": "<__MockObject-mock-id-1>",
455+
"id": "<mock-id-1>",
456456
"name": "<mock-value-for-field-\\"name\\">"
457457
},
458458
"backgroundImage": {
@@ -789,6 +789,38 @@ fragment TestFragment on User {
789789
}
790790
`;
791791

792+
exports[`generate payload for operation 1`] = `
793+
~~~~~~~~~~ INPUT ~~~~~~~~~~
794+
query TestQuery($id: ID!, $scale: Float) {
795+
node(id: $id) {
796+
... on User {
797+
name
798+
profile_picture(scale: $scale) {
799+
uri
800+
}
801+
}
802+
}
803+
}
804+
805+
~~~~~~~~~~ OUTPUT ~~~~~~~~~~
806+
{
807+
"variables": {
808+
"id": "<mock-id-1>",
809+
"scale": 4.2
810+
},
811+
"data": {
812+
"node": {
813+
"__typename": "User",
814+
"id": "<mock-id-1>",
815+
"name": "<mock-value-for-field-\\"name\\">",
816+
"profile_picture": {
817+
"uri": "<mock-value-for-field-\\"uri\\">"
818+
}
819+
}
820+
}
821+
}
822+
`;
823+
792824
exports[`should return \`null\` for selection if that is specified in default values 1`] = `
793825
~~~~~~~~~~ INPUT ~~~~~~~~~~
794826
fragment TestFragment on User {

0 commit comments

Comments
 (0)