From 1133469bd91ff76b9815e815a454a79d8e23a9bc Mon Sep 17 00:00:00 2001 From: Stephen Pittman Date: Thu, 15 Feb 2024 09:17:51 -0800 Subject: [PATCH] fix: strengthen MockedResponse.newData type (#11592) --- .api-reports/api-report-testing.md | 2 +- .api-reports/api-report-testing_core.md | 2 +- .changeset/dirty-insects-return.md | 5 ++ .../core/mocking/__tests__/mockLink.ts | 66 ++++++++++++++++++- src/testing/core/mocking/mockLink.ts | 2 +- 5 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 .changeset/dirty-insects-return.md diff --git a/.api-reports/api-report-testing.md b/.api-reports/api-report-testing.md index f57dfc0b93d..343bb599d38 100644 --- a/.api-reports/api-report-testing.md +++ b/.api-reports/api-report-testing.md @@ -933,7 +933,7 @@ export interface MockedResponse, TVariables = Record // (undocumented) maxUsageCount?: number; // (undocumented) - newData?: ResultFunction; + newData?: ResultFunction, TVariables>; // (undocumented) request: GraphQLRequest; // (undocumented) diff --git a/.api-reports/api-report-testing_core.md b/.api-reports/api-report-testing_core.md index bce86dc8645..c8121f60b5b 100644 --- a/.api-reports/api-report-testing_core.md +++ b/.api-reports/api-report-testing_core.md @@ -888,7 +888,7 @@ export interface MockedResponse, TVariables = Record // (undocumented) maxUsageCount?: number; // (undocumented) - newData?: ResultFunction; + newData?: ResultFunction, TVariables>; // (undocumented) request: GraphQLRequest; // (undocumented) diff --git a/.changeset/dirty-insects-return.md b/.changeset/dirty-insects-return.md new file mode 100644 index 00000000000..990a82e278c --- /dev/null +++ b/.changeset/dirty-insects-return.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +Strengthen `MockedResponse.newData` type diff --git a/src/testing/core/mocking/__tests__/mockLink.ts b/src/testing/core/mocking/__tests__/mockLink.ts index ffac583ceee..dc68b654505 100644 --- a/src/testing/core/mocking/__tests__/mockLink.ts +++ b/src/testing/core/mocking/__tests__/mockLink.ts @@ -1,7 +1,71 @@ import gql from "graphql-tag"; -import { MockLink } from "../mockLink"; +import { MockLink, MockedResponse } from "../mockLink"; import { execute } from "../../../../link/core/execute"; +describe("MockedResponse.newData", () => { + const setup = () => { + const weaklyTypedMockResponse: MockedResponse = { + request: { + query: gql` + query A { + a + } + `, + }, + }; + + const stronglyTypedMockResponse: MockedResponse< + { a: string }, + { input: string } + > = { + request: { + query: gql` + query A { + a + } + `, + }, + }; + + return { + weaklyTypedMockResponse, + stronglyTypedMockResponse, + }; + }; + + test("returned 'data' can be any object with untyped response", () => { + const { weaklyTypedMockResponse } = setup(); + + weaklyTypedMockResponse.newData = ({ fake: { faker } }) => ({ + data: { + pretend: faker, + }, + }); + }); + + test("can't return output that doesn't match TData", () => { + const { stronglyTypedMockResponse } = setup(); + + // @ts-expect-error return type does not match `TData` + stronglyTypedMockResponse.newData = () => ({ + data: { + a: 123, + }, + }); + }); + + test("can't use input variables that don't exist in TVariables", () => { + const { stronglyTypedMockResponse } = setup(); + + // @ts-expect-error unknown variables + stronglyTypedMockResponse.newData = ({ fake: { faker } }) => ({ + data: { + a: faker, + }, + }); + }); +}); + /* We've chosen this value as the MAXIMUM_DELAY since values that don't fit into a 32-bit signed int cause setTimeout to fire immediately */ diff --git a/src/testing/core/mocking/mockLink.ts b/src/testing/core/mocking/mockLink.ts index fd580eee6ce..46b43cca6ad 100644 --- a/src/testing/core/mocking/mockLink.ts +++ b/src/testing/core/mocking/mockLink.ts @@ -35,7 +35,7 @@ export interface MockedResponse< error?: Error; delay?: number; variableMatcher?: VariableMatcher; - newData?: ResultFunction; + newData?: ResultFunction, TVariables>; } export interface MockLinkOptions {