Skip to content

Commit 48f7386

Browse files
authored
Reduce duplicate custom scalars tests between core APIs and React hooks (#13368)
When I first started working on custom scalars, I added tests all over the place to ensure it works throughout the entirety of the library. The problem however is that I essentially duplicated the entire test suite across every React hook. Since all React hooks use `client.watchQuery` under the hood, `client.watchQuery` tests really should be the test suite that checks all the edge cases (fetch policies, defer/stream, etc.), otherwise future maintenance is going to be a nightmare if we have to duplicate new tests for every React hooks. The React hook custom scalars test suites are now reduced to a more minimal set to ensure the integration works as expected, but the core APIs are now where the full suite lives. This will make it easier to add tests in the future without having to duplicate them everywhere. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Expanded coverage for custom scalar parsing, including `Date` values returned through deferred and incremental responses. * Updated query, mutation, subscription, suspense, and preloader scenarios to validate parsed scalar fields and variables. * Added checks that identical scalar results preserve stable data references and avoid unnecessary updates. * Refined error-policy and loading-state expectations for successful parsed results. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 7aaa484 commit 48f7386

10 files changed

Lines changed: 362 additions & 7909 deletions

File tree

src/core/__tests__/client.mutate/customScalars.test.ts

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,17 @@ import {
99
NetworkStatus,
1010
} from "@apollo/client";
1111
import { InMemoryCache } from "@apollo/client/cache";
12+
import {
13+
Defer20220824Handler,
14+
GraphQL17Alpha9Handler,
15+
} from "@apollo/client/incremental";
1216
import { MockLink } from "@apollo/client/testing";
13-
import { dateScalar, ObservableStream } from "@apollo/client/testing/internal";
17+
import {
18+
dateScalar,
19+
mockDefer20220824,
20+
mockDeferStreamGraphQL17Alpha9,
21+
ObservableStream,
22+
} from "@apollo/client/testing/internal";
1423

1524
test("serializes scalar variables used in field arguments", async () => {
1625
let requestVariables!: OperationVariables;
@@ -857,3 +866,123 @@ test("parses custom scalar fields with an `ignore` error policy", async () => {
857866
},
858867
});
859868
});
869+
870+
test("parses custom scalar fields across `@defer` payloads (defer20220824)", async () => {
871+
const link = mockDefer20220824();
872+
const client = new ApolloClient({
873+
cache: new InMemoryCache({
874+
scalars: { Date: dateScalar },
875+
typePolicies: {
876+
Event: {
877+
fields: {
878+
startDate: { scalar: "Date" },
879+
endDate: { scalar: "Date" },
880+
},
881+
},
882+
},
883+
}),
884+
link: link.httpLink,
885+
incrementalHandler: new Defer20220824Handler(),
886+
});
887+
const mutation = gql`
888+
mutation CreateEvent {
889+
createEvent {
890+
id
891+
startDate
892+
... @defer {
893+
endDate
894+
}
895+
}
896+
}
897+
`;
898+
899+
const promise = client.mutate({ mutation });
900+
901+
link.enqueueInitialChunk({
902+
data: {
903+
createEvent: {
904+
__typename: "Event",
905+
id: "1",
906+
startDate: "2026-01-01",
907+
},
908+
},
909+
hasNext: true,
910+
});
911+
912+
link.enqueueSubsequentChunk({
913+
incremental: [{ data: { endDate: "2026-02-02" }, path: ["createEvent"] }],
914+
hasNext: false,
915+
});
916+
917+
await expect(promise).resolves.toStrictEqualTyped({
918+
data: {
919+
createEvent: {
920+
__typename: "Event",
921+
id: "1",
922+
startDate: new Date(2026, 0, 1),
923+
endDate: new Date(2026, 1, 2),
924+
},
925+
},
926+
});
927+
});
928+
929+
test("parses custom scalar fields across `@defer` payloads (graphql17Alpha9)", async () => {
930+
const link = mockDeferStreamGraphQL17Alpha9();
931+
const client = new ApolloClient({
932+
cache: new InMemoryCache({
933+
scalars: { Date: dateScalar },
934+
typePolicies: {
935+
Event: {
936+
fields: {
937+
startDate: { scalar: "Date" },
938+
endDate: { scalar: "Date" },
939+
},
940+
},
941+
},
942+
}),
943+
link: link.httpLink,
944+
incrementalHandler: new GraphQL17Alpha9Handler(),
945+
});
946+
const mutation = gql`
947+
mutation CreateEvent {
948+
createEvent {
949+
id
950+
startDate
951+
... @defer {
952+
endDate
953+
}
954+
}
955+
}
956+
`;
957+
958+
const promise = client.mutate({ mutation });
959+
960+
link.enqueueInitialChunk({
961+
data: {
962+
createEvent: {
963+
__typename: "Event",
964+
id: "1",
965+
startDate: "2026-01-01",
966+
},
967+
},
968+
pending: [{ id: "0", path: ["createEvent"] }],
969+
hasNext: true,
970+
});
971+
972+
link.enqueueSubsequentChunk({
973+
incremental: [{ data: { endDate: "2026-02-02" }, id: "0" }],
974+
completed: [{ id: "0" }],
975+
hasNext: false,
976+
});
977+
978+
await expect(promise).resolves.toStrictEqualTyped({
979+
data: {
980+
createEvent: {
981+
__typename: "Event",
982+
id: "1",
983+
startDate: new Date(2026, 0, 1),
984+
endDate: new Date(2026, 1, 2),
985+
},
986+
},
987+
});
988+
});

0 commit comments

Comments
 (0)