Skip to content

Commit

Permalink
Call createMockSchema inside createTestSchema (#11777)
Browse files Browse the repository at this point in the history
  • Loading branch information
alessbell authored Apr 12, 2024
1 parent e72cbba commit 5dfc79f
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 108 deletions.
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

0 comments on commit 5dfc79f

Please sign in to comment.