facebook / facebook/relay

[relay-test-utils] Unable to resolve operation that ask for data from client extensions only

Open
#4,927 4 comments 1 reaction 0 assignees View on GitHub
shared with relay team
Dominant language
Rust
Stars
19k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

We are experiencing a problem when testing relay components, particularly those which get data from client extensions only. I have prepared a reproduction in a form of unit test in `packages\relay-test-utils\__tests__\RelayMockEnvironmentWithComponents-test.js`

```js

describe('Test client extensions only', () => {
let testComponentTree;
beforeEach(() => {
environment = createMockEnvironment();
const ViewerQuery = graphql`
query RelayMockEnvironmentWithComponentsTestClientExtensionsOnlyQuery
@relay_test_operation {
client_root_field
}
`;
const TestComponent = () => (
{
if (props) {
// $FlowFixMe[incompatible-type]
return

{props.client_root_field}
;
} else if (error) {
// $FlowFixMe[incompatible-type]
return
{error.message}
;
}
// $FlowFixMe[incompatible-type]
return
Loading...
;
}}
/>
);
ReactTestRenderer.act(() => {
testComponentTree = ReactTestRenderer.create(
,
// $FlowFixMe[prop-missing]
{
unstable_isConcurrent: true,
},
);
});
});

it('should resolve operation with client extensions only', () => {
ReactTestRenderer.act(() => {
environment.mock.resolveMostRecentOperation(operation =>
MockPayloadGenerator.generate(
operation,
{
client_root_field: () => 'Hello, World!',
},
{mockClientData: true},
),
);
});
const messageValue = testComponentTree.root.find(
node => node.props.testID === 'helloMessage',
)?.children;
expect(messageValue).toEqual(['Hello, World!']);
});
});
```

In the current version of Relay the test fails as the actual value is `[]`:

``` ● ReactRelayTestMocker with Containers › Test client extensions only › should resolve operation with client extensions only

expect(received).toEqual(expected) // deep equality

- Expected - 3
+ Received + 1

- Array [
- "Hello, World!",
- ]
+ Array []
```

I debugged a bit and the operation never even reaches `execute` function of `RelayModernMockEnvironment`, so somewhere earlier the opearation is marked so not needing to go to resolvers. In theory it makes sense as no server fields were specified but we still want to be able to generate mock data for such operations. The current workaround we have is to add some dummy field to operation and just fetch `__typename` for it but it confuses other engineers within out team.

Are there any other options?

Contributor guide

Open the contributing guide

Research direction

Start with packages\relay-test-utils\__tests__\RelayMockEnvironmentWithComponents-test.js and run the reproduced client-extensions-only test. Trace environment.mock.resolveMostRecentOperation through RelayModernMockEnvironment, including why the operation does not reach execute. Done means the test resolves client_root_field to "Hello, World!" without requiring a dummy server field.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, javascript, react
Domain
frontend, testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.