Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call createMockSchema inside createTestSchema #11777

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 28 additions & 22 deletions .api-reports/api-report-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -449,11 +449,6 @@ type ConcastSourcesIterable<T> = Iterable<Source<T>>;
// @public (undocumented)
export function createMockClient<TData>(data: TData, query: DocumentNode, variables?: {}): ApolloClient<NormalizedCacheObject>;

// @alpha
export const createMockSchema: (staticSchema: GraphQLSchema, mocks: {
[key: string]: any;
}) => GraphQLSchema;

// @alpha
export const createSchemaFetch: (schema: GraphQLSchema, mockFetchOpts?: {
validate: boolean;
Expand All @@ -462,10 +457,11 @@ export const createSchemaFetch: (schema: GraphQLSchema, mockFetchOpts?: {
restore: () => void;
} & Disposable;

// Warning: (ae-forgotten-export) The symbol "TestSchemaOptions" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "ProxiedSchema" needs to be exported by the entry point index.d.ts
//
// @alpha
export const createTestSchema: (schemaWithMocks: GraphQLSchema, resolvers: Resolvers) => ProxiedSchema;
export const createTestSchema: (schemaWithTypeDefs: GraphQLSchema, options: TestSchemaOptions) => ProxiedSchema;

// @public (undocumented)
namespace DataProxy {
Expand Down Expand Up @@ -1286,24 +1282,10 @@ type Path = ReadonlyArray<string | number>;
// @public (undocumented)
type Primitive = null | undefined | string | number | boolean | symbol | bigint;

// Warning: (ae-forgotten-export) The symbol "ProxiedSchemaFns" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "TestSchemaFns" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ProxiedSchema = GraphQLSchema & ProxiedSchemaFns;

// @public (undocumented)
interface ProxiedSchemaFns {
// (undocumented)
add: (addOptions: {
resolvers: Resolvers;
}) => ProxiedSchema;
// (undocumented)
fork: (forkOptions?: {
resolvers?: Resolvers;
}) => ProxiedSchema;
// (undocumented)
reset: () => void;
}
type ProxiedSchema = GraphQLSchema & TestSchemaFns;

// @public (undocumented)
class QueryInfo {
Expand Down Expand Up @@ -1681,6 +1663,30 @@ interface SubscriptionOptions<TVariables = OperationVariables, TData = any> {
variables?: TVariables;
}

// @public (undocumented)
interface TestSchemaFns {
// (undocumented)
add: (addOptions: {
resolvers: Resolvers;
}) => ProxiedSchema;
// (undocumented)
fork: (forkOptions?: {
resolvers?: Resolvers;
}) => ProxiedSchema;
// (undocumented)
reset: () => void;
}

// @public (undocumented)
interface TestSchemaOptions {
// (undocumented)
resolvers: Resolvers;
// (undocumented)
scalars?: {
[key: string]: any;
};
}

// @public (undocumented)
export function tick(): Promise<void>;

Expand Down
45 changes: 28 additions & 17 deletions .api-reports/api-report-testing_core.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,10 +456,11 @@ export const createSchemaFetch: (schema: GraphQLSchema, mockFetchOpts?: {
restore: () => void;
} & Disposable;

// Warning: (ae-forgotten-export) The symbol "TestSchemaOptions" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "ProxiedSchema" needs to be exported by the entry point index.d.ts
//
// @alpha
export const createTestSchema: (schemaWithMocks: GraphQLSchema, resolvers: Resolvers) => ProxiedSchema;
export const createTestSchema: (schemaWithTypeDefs: GraphQLSchema, options: TestSchemaOptions) => ProxiedSchema;

// @public (undocumented)
namespace DataProxy {
Expand Down Expand Up @@ -1236,24 +1237,10 @@ type Path = ReadonlyArray<string | number>;
// @public (undocumented)
type Primitive = null | undefined | string | number | boolean | symbol | bigint;

// Warning: (ae-forgotten-export) The symbol "ProxiedSchemaFns" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "TestSchemaFns" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ProxiedSchema = GraphQLSchema & ProxiedSchemaFns;

// @public (undocumented)
interface ProxiedSchemaFns {
// (undocumented)
add: (addOptions: {
resolvers: Resolvers;
}) => ProxiedSchema;
// (undocumented)
fork: (forkOptions?: {
resolvers?: Resolvers;
}) => ProxiedSchema;
// (undocumented)
reset: () => void;
}
type ProxiedSchema = GraphQLSchema & TestSchemaFns;

// @public (undocumented)
class QueryInfo {
Expand Down Expand Up @@ -1633,6 +1620,30 @@ interface SubscriptionOptions<TVariables = OperationVariables, TData = any> {
variables?: TVariables;
}

// @public (undocumented)
interface TestSchemaFns {
// (undocumented)
add: (addOptions: {
resolvers: Resolvers;
}) => ProxiedSchema;
// (undocumented)
fork: (forkOptions?: {
resolvers?: Resolvers;
}) => ProxiedSchema;
// (undocumented)
reset: () => void;
}

// @public (undocumented)
interface TestSchemaOptions {
// (undocumented)
resolvers: Resolvers;
// (undocumented)
scalars?: {
[key: string]: any;
};
}

// @public (undocumented)
export function tick(): Promise<void>;

Expand Down
5 changes: 5 additions & 0 deletions .changeset/spotty-garlics-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@apollo/client": minor
---

Call `createMockSchema` inside `createTestSchema`.
1 change: 0 additions & 1 deletion src/__tests__/__snapshots__/exports.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,6 @@ Array [
"MockSubscriptionLink",
"MockedProvider",
"createMockClient",
"createMockSchema",
"createSchemaFetch",
"createTestSchema",
"itAsync",
Expand Down
96 changes: 52 additions & 44 deletions src/testing/core/__tests__/createTestSchema.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { createTestSchema } from "../createTestSchema.js";
import { GraphQLError, buildSchema } from "graphql";
import type { UseSuspenseQueryResult } from "../../../react/index.js";
import { useMutation, useSuspenseQuery } from "../../../react/index.js";
import { createMockSchema } from "../../graphql-tools/utils.js";
import userEvent from "@testing-library/user-event";
import { act, screen } from "@testing-library/react";
import { createSchemaFetch } from "../createSchemaFetch.js";
Expand Down Expand Up @@ -140,34 +139,35 @@ interface ViewerQueryData {
}

describe("schema proxy", () => {
const schemaWithMocks = createMockSchema(schemaWithTypeDefs, {
ID: () => "1",
Int: () => 42,
String: () => "String",
Date: () => new Date("January 1, 2024 01:00:00").toJSON().split("T")[0],
});

const schema = createTestSchema(schemaWithMocks, {
Query: {
viewer: () => ({
name: "Jane Doe",
book: {
text: "Hello World",
title: "The Book",
const schema = createTestSchema(schemaWithTypeDefs, {
resolvers: {
Query: {
viewer: () => ({
name: "Jane Doe",
book: {
text: "Hello World",
title: "The Book",
},
}),
},
Book: {
__resolveType: (obj) => {
if ("text" in obj) {
return "TextBook";
}
if ("colors" in obj) {
return "ColoringBook";
}
throw new Error("Could not resolve type");
},
}),
},
Book: {
__resolveType: (obj) => {
if ("text" in obj) {
return "TextBook";
}
if ("colors" in obj) {
return "ColoringBook";
}
throw new Error("Could not resolve type");
},
},
scalars: {
ID: () => "1",
Int: () => 42,
String: () => "String",
Date: () => new Date("January 1, 2024 01:00:00").toJSON().split("T")[0],
},
});

it("mocks scalars and resolvers", async () => {
Expand Down Expand Up @@ -849,27 +849,35 @@ describe("schema proxy", () => {
it("preserves resolvers from previous calls to .add on subsequent calls to .fork", async () => {
let name = "Virginia";

const schema = createTestSchema(schemaWithMocks, {
Query: {
viewer: () => ({
name,
book: {
text: "Hello World",
title: "The Book",
const schema = createTestSchema(schemaWithTypeDefs, {
resolvers: {
Query: {
viewer: () => ({
name,
book: {
text: "Hello World",
title: "The Book",
},
}),
},
Book: {
__resolveType: (obj) => {
if ("text" in obj) {
return "TextBook";
}
if ("colors" in obj) {
return "ColoringBook";
}
throw new Error("Could not resolve type");
},
}),
},
Book: {
__resolveType: (obj) => {
if ("text" in obj) {
return "TextBook";
}
if ("colors" in obj) {
return "ColoringBook";
}
throw new Error("Could not resolve type");
},
},
scalars: {
ID: () => "1",
Int: () => 42,
String: () => "String",
Date: () => new Date("January 1, 2024 01:00:00").toJSON().split("T")[0],
},
});

schema.add({
Expand Down
57 changes: 34 additions & 23 deletions src/testing/core/createTestSchema.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { addResolversToSchema } from "@graphql-tools/schema";
import type { GraphQLSchema } from "graphql";

import { createMockSchema } from "../graphql-tools/utils.js";
import type { Resolvers } from "../../core/types.js";

type ProxiedSchema = GraphQLSchema & ProxiedSchemaFns;
type ProxiedSchema = GraphQLSchema & TestSchemaFns;

interface ProxiedSchemaFns {
interface TestSchemaFns {
add: (addOptions: { resolvers: Resolvers }) => ProxiedSchema;
fork: (forkOptions?: { resolvers?: Resolvers }) => ProxiedSchema;
reset: () => void;
}

interface TestSchemaOptions {
resolvers: Resolvers;
scalars?: { [key: string]: any };
}

/**
* A function that creates a [Proxy object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
* around a given `schema` with `resolvers`. This proxied schema can be used to
Expand All @@ -19,41 +25,43 @@ interface ProxiedSchemaFns {
* can be modified independently of the original schema. `reset` will restore
* resolvers to the original proxied schema.
*
* @param schemaWithMocks - A `GraphQLSchema`.
* @param resolvers - `Resolvers` object.
* @param schema - A `GraphQLSchema`.
* @param options - An `options` object that accepts `scalars` and `resolvers` objects.
* @returns A `ProxiedSchema` with `add`, `fork` and `reset` methods.
*
* @example
* ```js
* const schemaWithMocks = createMockSchema(schemaWithTypeDefs, {
ID: () => "1",
Int: () => 36,
String: () => "String",
Date: () => new Date("December 10, 1815 01:00:00").toJSON().split("T")[0],
});
*
* const schema = createTestSchema(schemaWithMocks, {
Query: {
writer: () => ({
name: "Ada Lovelace",
}),
* const schema = createTestSchema(schemaWithTypeDefs, {
* resolvers: {
Query: {
writer: () => ({
name: "Ada Lovelace",
}),
}
},
scalars: {
ID: () => "1",
Int: () => 36,
String: () => "String",
Date: () => new Date("December 10, 1815 01:00:00").toJSON().split("T")[0],
}
});
* ```
* @since 3.9.0
* @alpha
*/
const createTestSchema = (
schemaWithMocks: GraphQLSchema,
resolvers: Resolvers
schemaWithTypeDefs: GraphQLSchema,
options: TestSchemaOptions
): ProxiedSchema => {
let targetResolvers = { ...resolvers };
let targetResolvers = { ...options.resolvers };
let targetSchema = addResolversToSchema({
schema: schemaWithMocks,
schema: createMockSchema(schemaWithTypeDefs, options.scalars ?? {}),
resolvers: targetResolvers,
});

const fns: ProxiedSchemaFns = {
const fns: TestSchemaFns = {
add: ({ resolvers: newResolvers }) => {
targetResolvers = { ...targetResolvers, ...newResolvers };
targetSchema = addResolversToSchema({
Expand All @@ -65,13 +73,16 @@ const createTestSchema = (
},

fork: ({ resolvers: newResolvers } = {}) => {
return createTestSchema(targetSchema, newResolvers ?? targetResolvers);
return createTestSchema(targetSchema, {
resolvers: newResolvers ?? targetResolvers,
scalars: options.scalars,
});
},

reset: () => {
targetSchema = addResolversToSchema({
schema: schemaWithMocks,
resolvers,
schema: schemaWithTypeDefs,
resolvers: options.resolvers,
});
},
};
Expand Down
Loading
Loading