facebook / facebook/relay

MockPayloadGenerator: __typename mocking depends on generated request ordering

Open
#3,744 2 comments 0 reactions 0 assignees View on GitHub
bug rust
Dominant language
Rust
Stars
19k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

We have a regression between v12 and v13 in example queries using `MockPayloadGenerator`.

This is caused by a bug in MockPayloadGenerator, but appears as a regression when upgrading.

It has to do with the feature where the `__typename` is correctly provided in the mock payload if you don't provide a `__typename` value in the mock data.

Assume we have these 2 selections _generated by the compiler(s)_:
```js
const generalSelection = {
kind: 'InlineFragment',
selections: [
{
kind: 'ScalarField',
name: 'id',
},
],
type: 'TypeB',
};

const typenameSelection = {
kind: 'ScalarField',
name: '__typename',
};
```

For a query that looks like this
```graphql
query testQuery {
a {
b {
... on TypeB {
id
}
__typename
}
}
}
```

These 2 selections are going to be in a request under a linked field

```js
const dummyOperationDescriptor = (items) => ({
request: {
node: { // <-- the generated ConcreteRequest
operation: {
name: 'testQuery',
selections: [
{
concreteType: 'TypeA',
kind: 'LinkedField',
name: 'a',
selections: [
{
concreteType: null,
kind: 'LinkedField',
name: 'b',
plural: false,
selections: items, // <-- here's the order-dependent list
},
],
},
],
},
params: {
metadata: {},
},
},
variables: {},
cacheConfig: {},
},
});
```

The JS compiler always output the `__typename` field first in this list of selections
```js
const working = RelayMockPayloadGenerator.generate(dummyOperationDescriptor([
typenameSelection,
generalSelection
]));
```
Which leads to this (correct) output
```json
{
"data": {
"a": {
"b": {
"__typename": "TypeB",
"id": ""
}
}
}
}
```

The rust compiler changed the output ordering of fields, and `__typename` is no longer first.

```js
const failing = RelayMockPayloadGenerator.generate(dummyOperationDescriptor([
generalSelection,
typenameSelection
]));
```

Now this gives us incorrect output
```json
{
"data": {
"a": {
"b": {
"__typename": "__MockObject",
"id": ""
}
}
}
}
```
This means that queries that we're previously mocked fine no longer work

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.