Skip to content

Commit c9cae0a

Browse files
authored
simplify missingFieldHandlers (#589)
* simplify missingFieldHandlers * make the bindings closer to flow types * update changelog * fix comments * add tests for missing field handlers
1 parent cb93ea8 commit c9cae0a

16 files changed

+1152
-130
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# master
22

3+
- Simplify `missingFieldHandlers`. https://github.com/zth/rescript-relay/pull/589
4+
35
# 4.1.0
46

57
- Add support for `autoExhaustiveTypes` config and a `@nonExhaustive` directive to control automatic exhaustive checks for unions/interfaces.

packages/rescript-relay/__tests__/Test_misingFieldHandlers-tests.js renamed to packages/rescript-relay/__tests__/Test_misingFieldHandlersLinked-tests.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
require("@testing-library/jest-dom/extend-expect");
22
const t = require("@testing-library/react");
3-
const React = require("react");
43
const queryMock = require("./queryMock");
54

6-
const { test_missingFieldHandlers } = require("./Test_missingFieldHandlers.bs");
5+
const { test_missingFieldHandlers } = require("./Test_missingFieldHandlersLinked.bs");
76
const { fireEvent } = require("@testing-library/react");
87
const ReactTestUtils = require("react-dom/test-utils");
98

10-
describe("Missing field handlers", () => {
9+
describe("Missing linked field handlers", () => {
1110
test("resolves nodes via top level node field from cache automatically", async () => {
1211
queryMock.mockQuery({
13-
name: "TestMissingFieldHandlersMeQuery",
12+
name: "TestMissingFieldHandlersLinkedMeQuery",
1413
data: {
1514
loggedInUser: {
1615
firstName: "First",
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
require("@testing-library/jest-dom/extend-expect");
2+
const t = require("@testing-library/react");
3+
const queryMock = require("./queryMock");
4+
5+
const { test_missingFieldHandlers } = require("./Test_missingFieldHandlersPlural.bs");
6+
const { fireEvent } = require("@testing-library/react");
7+
const ReactTestUtils = require("react-dom/test-utils");
8+
9+
describe("Missing plural linked field handlers for user", () => {
10+
test("resolves a plural linked record field via an equivalent field from cache automatically", async () => {
11+
queryMock.mockQuery({
12+
name: "TestMissingFieldHandlersPluralQuery",
13+
data: {
14+
topOnlineUserList: [
15+
{
16+
firstName: "Björn",
17+
id: "123",
18+
},
19+
{
20+
firstName: "Sven",
21+
id: "456",
22+
},
23+
]
24+
},
25+
});
26+
27+
t.render(test_missingFieldHandlers());
28+
await t.screen.findByText("1: Björn - Sven");
29+
30+
ReactTestUtils.act(() => {
31+
fireEvent.click(t.screen.getByText("Show next"));
32+
});
33+
await t.screen.findByText("2: Björn - Sven");
34+
});
35+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require("@testing-library/jest-dom/extend-expect");
2+
const t = require("@testing-library/react");
3+
const queryMock = require("./queryMock");
4+
5+
const { test_missingFieldHandlers } = require("./Test_missingFieldHandlersScalar.bs");
6+
const { fireEvent } = require("@testing-library/react");
7+
const ReactTestUtils = require("react-dom/test-utils");
8+
9+
describe("Missing scalar field handlers", () => {
10+
test("resolves nodes via top level node field plus scalar equivalence from cache automatically", async () => {
11+
queryMock.mockQuery({
12+
name: "TestMissingFieldHandlersScalarMeQuery",
13+
data: {
14+
loggedInUser: {
15+
lastName: "Last",
16+
id: "123",
17+
},
18+
},
19+
});
20+
21+
t.render(test_missingFieldHandlers());
22+
await t.screen.findByText("1: Last");
23+
24+
ReactTestUtils.act(() => {
25+
fireEvent.click(t.screen.getByText("Show next"));
26+
});
27+
await t.screen.findByText("2: Last");
28+
});
29+
});

packages/rescript-relay/__tests__/Test_missingFieldHandlers.res renamed to packages/rescript-relay/__tests__/Test_missingFieldHandlersLinked.res

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Query = %relay(`
2-
query TestMissingFieldHandlersQuery {
2+
query TestMissingFieldHandlersLinkedQuery {
33
node(id: "123") {
44
... on User {
55
firstName
@@ -9,7 +9,7 @@ module Query = %relay(`
99
`)
1010

1111
module MeQuery = %relay(`
12-
query TestMissingFieldHandlersMeQuery {
12+
query TestMissingFieldHandlersLinkedMeQuery {
1313
loggedInUser {
1414
firstName
1515
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
module Query = %relay(`
2+
query TestMissingFieldHandlersPluralQuery {
3+
topOnlineUserList {
4+
firstName
5+
}
6+
}
7+
`)
8+
9+
module BestiesQuery = %relay(`
10+
query TestMissingFieldHandlersPluralBestiesQuery {
11+
onlineBesties {
12+
firstName
13+
}
14+
}
15+
`)
16+
17+
module RenderBesties = {
18+
@react.component
19+
let make = () => {
20+
let query = BestiesQuery.use(~variables=(), ~fetchPolicy=StoreOnly)
21+
22+
React.string(
23+
"2: " ++
24+
query.onlineBesties
25+
->Option.getOr([])
26+
->Array.keepSome
27+
->Array.map(({firstName}) => firstName)
28+
->Array.join(" - "),
29+
)
30+
}
31+
}
32+
33+
module Test = {
34+
@react.component
35+
let make = () => {
36+
let query = Query.use(~variables=())
37+
let (showNext, setShowNext) = React.useState(() => false)
38+
39+
<>
40+
<div>
41+
{React.string(
42+
"1: " ++
43+
query.topOnlineUserList
44+
->Option.getOr([])
45+
->Array.keepSome
46+
->Array.map(({firstName}) => firstName)
47+
->Array.join(" - "),
48+
)}
49+
</div>
50+
{showNext
51+
? <RenderBesties />
52+
: <button onClick={_ => setShowNext(_ => true)}> {React.string("Show next")} </button>}
53+
</>
54+
}
55+
}
56+
57+
@live
58+
let test_missingFieldHandlers = () => {
59+
let network = RescriptRelay.Network.makePromiseBased(~fetchFunction=RelayEnv.fetchQuery)
60+
61+
let environment = RescriptRelay.Environment.make(
62+
~network,
63+
~store=RescriptRelay.Store.make(~source=RescriptRelay.RecordSource.make()),
64+
~missingFieldHandlers=[
65+
PluralLinked({
66+
handle: (field, record, _args, _store) =>
67+
switch (record, field.name) {
68+
| (Value(record), "onlineBesties") =>
69+
module RP = RescriptRelay.RecordProxy
70+
RP.getLinkedRecords(record, ~name="topOnlineUserList")
71+
->Option.map(array =>
72+
Array.map(array, record => Option.map(record, RP.getDataId)->Nullable.fromOption)
73+
)
74+
->Nullable.fromOption
75+
| _ => undefined
76+
},
77+
}),
78+
],
79+
)
80+
81+
<TestProviders.Wrapper environment>
82+
<Test />
83+
</TestProviders.Wrapper>
84+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
module Query = %relay(`
2+
query TestMissingFieldHandlersScalarQuery {
3+
node(id: "123") {
4+
... on User {
5+
surname
6+
}
7+
}
8+
}
9+
`)
10+
11+
module MeQuery = %relay(`
12+
query TestMissingFieldHandlersScalarMeQuery {
13+
loggedInUser {
14+
lastName
15+
}
16+
}
17+
`)
18+
19+
module RenderMe = {
20+
@react.component
21+
let make = () => {
22+
let query = Query.use(~variables=(), ~fetchPolicy=StoreOnly)
23+
24+
switch query.node {
25+
| Some(User(user)) => React.string("2: " ++ user.surname)
26+
| _ => React.string("-")
27+
}
28+
}
29+
}
30+
31+
module Test = {
32+
@react.component
33+
let make = () => {
34+
let query = MeQuery.use(~variables=())
35+
let (showNext, setShowNext) = React.useState(() => false)
36+
37+
<>
38+
<div> {React.string("1: " ++ query.loggedInUser.lastName)} </div>
39+
{showNext
40+
? <RenderMe />
41+
: <button onClick={_ => setShowNext(_ => true)}> {React.string("Show next")} </button>}
42+
</>
43+
}
44+
}
45+
46+
@live
47+
let test_missingFieldHandlers = () => {
48+
let network = RescriptRelay.Network.makePromiseBased(~fetchFunction=RelayEnv.fetchQuery)
49+
50+
let environment = RescriptRelay.Environment.make(
51+
~network,
52+
~store=RescriptRelay.Store.make(~source=RescriptRelay.RecordSource.make()),
53+
~missingFieldHandlers=[
54+
Scalar({
55+
handle: (field, record, _args, _store) =>
56+
switch (record, field.name) {
57+
| (Value(record), "surname") if RescriptRelay.RecordProxy.getType(record) === "User" =>
58+
RescriptRelay.RecordProxy.getValueString(record, ~name="lastName")->Nullable.fromOption
59+
| _ => undefined
60+
},
61+
}),
62+
],
63+
)
64+
65+
<TestProviders.Wrapper environment>
66+
<Test />
67+
</TestProviders.Wrapper>
68+
}

packages/rescript-relay/__tests__/__generated__/TestMissingFieldHandlersMeQuery_graphql.res renamed to packages/rescript-relay/__tests__/__generated__/TestMissingFieldHandlersLinkedMeQuery_graphql.res

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/rescript-relay/__tests__/__generated__/TestMissingFieldHandlersQuery_graphql.res renamed to packages/rescript-relay/__tests__/__generated__/TestMissingFieldHandlersLinkedQuery_graphql.res

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)