-
Notifications
You must be signed in to change notification settings - Fork 74
/
renderRelayTree.tsx
109 lines (105 loc) · 3.25 KB
/
renderRelayTree.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { LoadingClassName } from "Artsy/Relay/renderWithLoadProgress"
import "DevTools/renderUntil"
import { mount, RenderUntilPredicate } from "enzyme"
import React from "react"
import { MockRelayRenderer, MockRelayRendererProps } from "./MockRelayRenderer"
/**
* A {@link ReactWrapper.prototype.renderUntil} callback implementation that
* passes when no more loading indicators exist in the tree. Use this when you
* need to use `renderUntil` directly, such as after making updates to a Relay
* tree.
*/
export const RelayFinishedLoading: RenderUntilPredicate<any, any, any> = tree =>
!tree.find(`.${LoadingClassName}`).length
/**
* Renders a tree of Relay containers with a mocked local instance of the
* metaphysics schema and resolves the returned promise once loading data and
* rendering (including waterfall requests) has finished.
*
* It does this by checking the tree for the existence of an element with the
* class defined by `LoadingClassName` from the `renderWithLoadProgress` module.
* I.e. as long as at least 1 element exists in the tree with that class name,
* rendering is not considered finished. Use the `renderWithLoadProgress`
* function for your `QueryRenderer` where possible, as it will do this plumbing
* by default.
*
* @note
* Use this function in tests, but not storybooks. For storybooks you should
* usually use {@link MockRelayRenderer}.
*
* @param params
* See {@link MockRelayRenderer}
*
* @param until
* An optional predicate function that is used to test wether rendering should
* be considered finished. This is a regular enzyme wrapper.
*
* @param wrapper
* An optional component that the Relay tree should be nested in. Use this to
* e.g. setup any context provider components etc.
*
* @example
*
```tsx
jest.unmock("react-relay")
const Artwork = createFragmentContainer(
props => (
<div>
<span>{props.artwork.title}}</span>
<img src={props.artwork.image.url} />
</div>
),
graphql`
fragment MockRelayRenderer_artwork on Artwork {
image {
url
}
}
`
)
it("renders a Relay tree", () => {
return renderRelayTree({
Component: Artwork,
query: graphql`
query MockRelayRendererQuery {
artwork(id: "mona-lisa") {
...MockRelayRenderer_artwork
}
}
`,
mockResolvers: {
Artwork: () => ({
title: "Mona Lisa",
image: {
url: "http://test/image.jpg",
},
}),
},
}).then(wrapper => {
expect(wrapper.find("span").text()).toEqual("Mona Lisa")
expect(wrapper.find("img").props().src).toEqual("http://test/image.jpg")
})
})
```
*
*/
export function renderRelayTree<
P = {},
S = {},
C extends React.Component = React.Component
>(
params: MockRelayRendererProps<any> & {
renderUntil?: RenderUntilPredicate<P, S, C>
wrapper?: (renderer: JSX.Element) => JSX.Element
}
) {
const {
renderUntil: renderUntilPredicate,
wrapper,
...rendererProps
} = params
const renderer = <MockRelayRenderer {...rendererProps} />
return mount<C, P, S>(wrapper ? wrapper(renderer) : renderer).renderUntil(
renderUntilPredicate || RelayFinishedLoading
)
}