@shopify/graphql-testing
Advanced tools
Comparing version 0.0.0-snapshot-20230210053510 to 0.0.0-snapshot-20230213141306
@@ -5,3 +5,5 @@ 'use strict'; | ||
var client = require('@apollo/client'); | ||
var apolloLink = require('apollo-link'); | ||
var apolloCacheInmemory = require('apollo-cache-inmemory'); | ||
var client = require('./client.js'); | ||
var operations = require('./operations.js'); | ||
@@ -14,4 +16,6 @@ var utilities = require('./utilities.js'); | ||
constructor(mock = {}, { | ||
unionOrIntersectionTypes = [], | ||
cacheOptions = {}, | ||
links = [] | ||
links = [], | ||
assumeImmutableResults = false | ||
} = {}) { | ||
@@ -33,9 +37,19 @@ this.client = void 0; | ||
const cache = new client.InMemoryCache(cacheOptions); | ||
const cache = new apolloCacheInmemory.InMemoryCache({ | ||
fragmentMatcher: new apolloCacheInmemory.IntrospectionFragmentMatcher({ | ||
introspectionQueryResultData: { | ||
__schema: { | ||
types: unionOrIntersectionTypes | ||
} | ||
} | ||
}), | ||
...cacheOptions | ||
}); | ||
this.mockLink = new mocks.MockLink(mock); | ||
const link = client.ApolloLink.from([...links, new inflight.InflightLink({ | ||
const link = apolloLink.ApolloLink.from([...links, new inflight.InflightLink({ | ||
onCreated: this.handleCreate, | ||
onResolved: this.handleResolve | ||
}), this.mockLink]); | ||
this.client = new client.ApolloClient({ | ||
this.client = new client.TestingApolloClient({ | ||
assumeImmutableResults, | ||
link, | ||
@@ -55,25 +69,27 @@ cache | ||
async resolveAll(options = {}) { | ||
const finalOperationName = utilities.operationNameFromFindOptions(options); | ||
await this.withWrapper(async () => { | ||
let requestFilter; | ||
if (Object.keys(options).length) { | ||
const finalOperationName = utilities.operationNameFromFindOptions(options); | ||
requestFilter = ({ | ||
operation | ||
}) => { | ||
const nameMatchesOrWasNotSet = finalOperationName ? finalOperationName === operation.operationName : true; | ||
const customFilterMatchesOrWasNotSet = options.filter ? options.filter(operation) : true; | ||
return nameMatchesOrWasNotSet && customFilterMatchesOrWasNotSet; | ||
}; | ||
} | ||
await this.wrappers.reduce((perform, wrapper) => { | ||
return () => wrapper(perform); | ||
}, async () => { | ||
const allPendingRequests = Array.from(this.pendingRequests); | ||
const matchingRequests = finalOperationName ? allPendingRequests.filter(({ | ||
operation: { | ||
operationName | ||
} | ||
}) => operationName === finalOperationName) : allPendingRequests; | ||
const matchingRequests = requestFilter ? allPendingRequests.filter(requestFilter) : allPendingRequests; | ||
await Promise.all(matchingRequests.map(({ | ||
resolve | ||
}) => resolve())); | ||
}); | ||
})(); | ||
} | ||
async waitForQueryUpdates() { | ||
// queryManager is an internal implementation detail that is a TS-private | ||
// property. We can access it in JS but TS thinks we can't so cast to any | ||
// to shut typescript up | ||
await this.withWrapper(async () => { | ||
await this.client.queryManager.broadcastQueries(); | ||
}); | ||
} | ||
wrap(wrapper) { | ||
@@ -83,12 +99,4 @@ this.wrappers.push(wrapper); | ||
async withWrapper(cb) { | ||
await this.wrappers.reduce((perform, wrapper) => { | ||
return () => wrapper(perform); | ||
}, async () => { | ||
await cb(); | ||
})(); | ||
} | ||
} | ||
exports.GraphQL = GraphQL; |
@@ -5,5 +5,5 @@ 'use strict'; | ||
var client = require('@apollo/client'); | ||
var apolloLink = require('apollo-link'); | ||
class InflightLink extends client.ApolloLink { | ||
class InflightLink extends apolloLink.ApolloLink { | ||
constructor(options) { | ||
@@ -32,3 +32,3 @@ super(); | ||
this.options.onCreated(request); | ||
return new client.Observable(observer => { | ||
return new apolloLink.Observable(observer => { | ||
return nextLink(operation).subscribe({ | ||
@@ -35,0 +35,0 @@ complete() { |
@@ -5,6 +5,6 @@ 'use strict'; | ||
var client = require('@apollo/client'); | ||
var apolloLink = require('apollo-link'); | ||
var graphql = require('graphql'); | ||
class MockLink extends client.ApolloLink { | ||
class MockLink extends apolloLink.ApolloLink { | ||
constructor(mock) { | ||
@@ -20,3 +20,3 @@ super(); | ||
request(operation) { | ||
return new client.Observable(obs => { | ||
return new apolloLink.Observable(obs => { | ||
const { | ||
@@ -23,0 +23,0 @@ mock |
@@ -7,5 +7,6 @@ 'use strict'; | ||
query, | ||
mutation | ||
mutation, | ||
operationName | ||
}) { | ||
const passedOptions = [query, mutation].filter(Boolean); | ||
const passedOptions = [query, mutation, operationName].filter(Boolean); | ||
@@ -15,6 +16,6 @@ if (passedOptions.length === 0) { | ||
} else if (passedOptions.length > 1) { | ||
throw new Error('You can only pass one of query or mutation'); | ||
throw new Error('You can only pass one of query, mutation, or operationName when finding a GraphQL operation'); | ||
} | ||
return operationNameFromDocument(query || mutation); | ||
return operationName || operationNameFromDocument(query || mutation); | ||
} | ||
@@ -21,0 +22,0 @@ function operationNameFromDocument(document) { |
@@ -1,8 +0,15 @@ | ||
import { ApolloClient, ApolloLink, InMemoryCacheConfig } from '@apollo/client'; | ||
import { ApolloLink } from 'apollo-link'; | ||
import { InMemoryCacheConfig } from 'apollo-cache-inmemory'; | ||
import { ApolloClient } from 'apollo-client'; | ||
import { Operations } from './operations'; | ||
import { GraphQLMock, FindOptions } from './types'; | ||
import { GraphQLMock, MockRequest, FindOptions } from './types'; | ||
export interface Options { | ||
unionOrIntersectionTypes?: any[]; | ||
cacheOptions?: InMemoryCacheConfig; | ||
links?: ApolloLink[]; | ||
assumeImmutableResults?: boolean; | ||
} | ||
interface ResolveAllFindOptions extends FindOptions { | ||
filter?: (operation: MockRequest['operation']) => boolean; | ||
} | ||
interface Wrapper { | ||
@@ -17,12 +24,10 @@ (perform: () => Promise<void>): Promise<void>; | ||
private readonly mockLink; | ||
constructor(mock?: GraphQLMock, { cacheOptions, links }?: Options); | ||
constructor(mock?: GraphQLMock, { unionOrIntersectionTypes, cacheOptions, links, assumeImmutableResults, }?: Options); | ||
update(mock: GraphQLMock): void; | ||
resolveAll(options?: FindOptions): Promise<void>; | ||
waitForQueryUpdates(): Promise<void>; | ||
resolveAll(options?: ResolveAllFindOptions): Promise<void>; | ||
wrap(wrapper: Wrapper): void; | ||
private handleCreate; | ||
private handleResolve; | ||
private withWrapper; | ||
} | ||
export {}; | ||
//# sourceMappingURL=graphql-controller.d.ts.map |
@@ -1,2 +0,2 @@ | ||
import { ApolloLink, Observable, Operation, NextLink, FetchResult } from '@apollo/client'; | ||
import { ApolloLink, Observable, Operation, NextLink, FetchResult } from 'apollo-link'; | ||
import { MockRequest } from '../types'; | ||
@@ -3,0 +3,0 @@ interface Options { |
@@ -1,2 +0,2 @@ | ||
import { ApolloLink, Observable, Operation } from '@apollo/client'; | ||
import { ApolloLink, Observable, Operation } from 'apollo-link'; | ||
import { GraphQLMock } from '../types'; | ||
@@ -3,0 +3,0 @@ export declare class MockLink extends ApolloLink { |
@@ -1,2 +0,2 @@ | ||
import { Operation } from '@apollo/client'; | ||
import { Operation } from 'apollo-link'; | ||
export declare function assertIsGraphQL(graphQL: unknown, { expectation, isNot }: { | ||
@@ -3,0 +3,0 @@ expectation: string; |
@@ -1,2 +0,2 @@ | ||
import { Operation } from '@apollo/client'; | ||
import { Operation } from 'apollo-link'; | ||
import { FindOptions } from './types'; | ||
@@ -3,0 +3,0 @@ export declare class Operations { |
import { DocumentNode } from 'graphql'; | ||
import { GraphQLRequest, Operation } from '@apollo/client'; | ||
import { GraphQLRequest, Operation } from 'apollo-link'; | ||
export interface FindOptions { | ||
@@ -10,2 +10,6 @@ query?: DocumentNode | { | ||
mutation?: DocumentNode; | ||
/** | ||
* @deprecated Please use `query` or `mutation` instead. | ||
*/ | ||
operationName?: string; | ||
} | ||
@@ -12,0 +16,0 @@ export type MockGraphQLResponse = Error | object; |
import { DocumentNode } from 'graphql'; | ||
import { FindOptions } from './types'; | ||
export declare function operationNameFromFindOptions({ query, mutation }: FindOptions): string | undefined; | ||
export declare function operationNameFromFindOptions({ query, mutation, operationName, }: FindOptions): string | undefined; | ||
export declare function operationNameFromDocument(document: DocumentNode | { | ||
@@ -5,0 +5,0 @@ resolver: { |
{ | ||
"name": "@shopify/graphql-testing", | ||
"version": "0.0.0-snapshot-20230210053510", | ||
"version": "0.0.0-snapshot-20230213141306", | ||
"license": "MIT", | ||
@@ -34,3 +34,5 @@ "description": "Utilities to create mock GraphQL factories", | ||
"dependencies": { | ||
"@apollo/client": "^3.5.8", | ||
"apollo-cache-inmemory": ">=1.0.0 <2.0.0", | ||
"apollo-client": ">=2.0.0 <3.0.0", | ||
"apollo-link": ">=1.0.0 <2.0.0", | ||
"graphql": ">=14.5.0 <16.0.0", | ||
@@ -37,0 +39,0 @@ "jest-matcher-utils": "^26.6.2" |
@@ -20,9 +20,7 @@ # `@shopify/graphql-testing` | ||
The default utility exported by this library is `createGraphQLFactory`. This factory accepts an optional options argument that allows you to pass a `cacheOptions` that will be used to construct an Apollo in-memory cache and/ or `links` which can contain `ApolloLink`s that will be passed to the apollo client links. | ||
The default utility exported by this library is `createGraphQLFactory`. This factory accepts an optional options argument that allows you to pass a `unionOrIntersectionTypes` array and/ or additional `cacheOptions` that will be used to construct an Apollo in-memory cache and/ or `links` which can contain `ApolloLink`s that will be passed to the apollo client links. | ||
```js | ||
const createGraphQL = createGraphQLFactory({ | ||
cacheOptions: { | ||
possibleTypes: {}, | ||
}, | ||
unionOrIntersectionTypes: [], | ||
}); | ||
@@ -54,3 +52,3 @@ ``` | ||
You can also pass a `query` or `mutation` option to `resolveAll`, which will filter the pending operations and only resolve the ones with a matching operation. | ||
You can also pass a `query`, `mutation` or `filter` option to `resolveAll`. `query` and `mutation` will filter the pending operations and only resolve the ones with a matching operation. `filter` allows you to write your own custom filter function based upon the operation, for instace this will allow you to filter by the variables passed to the query. If `filter` is passed in addition to `query` or `mutation` then both filters shall be applied. | ||
@@ -61,13 +59,14 @@ ```js | ||
```js | ||
await graphQL.resolveAll({ | ||
query: petQuery, | ||
filter: (operation) => operation.variables.id === '1', | ||
}); | ||
``` | ||
Note that, until a GraphQL operation has been resolved, it does not appear in the `operations` list described below. | ||
#### `waitForQueryUpdates()` | ||
Apollo 3.6.0+ batches updates to the cache asynchronously. This means that in cases where you trigger fetching more data using `fetchMore` often the cache is persisted in the next tick and thus the component making the query does not update in the expected act block. This can result in flaky tests where you request data, and use resolveAll to fetch it, but the React component under test does not update. | ||
The `waitForQueryUpdates()` method shall ensure all cache updates are resolved. | ||
#### `wrap()` | ||
The `wrap()` method allows you to wrap all calls to `resolveAll()` and `waitForQueryUpdates()` in a function call. This can be useful when working with React components, which require that all operations that lead to state changes be wrapped in an `act()` call. The following example demonstrates using this with [`@shopify/react-testing`](../react-testing): | ||
The `wrap()` method allows you to wrap all GraphQL resolutions in a function call. This can be useful when working with React components, which require that all operations that lead to state changes be wrapped in an `act()` call. The following example demonstrates using this with [`@shopify/react-testing`](../react-testing): | ||
@@ -74,0 +73,0 @@ ```tsx |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
66574
67
909
5
190
+ Addedapollo-client@>=2.0.0 <3.0.0
+ Addedapollo-link@>=1.0.0 <2.0.0
+ Added@types/zen-observable@0.8.7(transitive)
+ Added@wry/context@0.4.4(transitive)
+ Added@wry/equality@0.1.11(transitive)
+ Addedapollo-cache@1.3.5(transitive)
+ Addedapollo-cache-inmemory@1.6.6(transitive)
+ Addedapollo-client@2.6.10(transitive)
+ Addedapollo-link@1.2.14(transitive)
+ Addedapollo-utilities@1.3.4(transitive)
+ Addedfast-json-stable-stringify@2.1.0(transitive)
+ Addedoptimism@0.10.3(transitive)
+ Addedsymbol-observable@1.2.0(transitive)
+ Addedts-invariant@0.4.4(transitive)
+ Addedtslib@1.14.1(transitive)
+ Addedzen-observable-ts@0.8.21(transitive)
- Removed@apollo/client@^3.5.8
- Removed@apollo/client@3.12.3(transitive)
- Removed@graphql-typed-document-node/core@3.2.0(transitive)
- Removed@wry/caches@1.0.1(transitive)
- Removed@wry/context@0.7.4(transitive)
- Removed@wry/equality@0.5.7(transitive)
- Removed@wry/trie@0.5.0(transitive)
- Removedgraphql-tag@2.12.6(transitive)
- Removedhoist-non-react-statics@3.3.2(transitive)
- Removedjs-tokens@4.0.0(transitive)
- Removedloose-envify@1.4.0(transitive)
- Removedobject-assign@4.1.1(transitive)
- Removedoptimism@0.18.1(transitive)
- Removedprop-types@15.8.1(transitive)
- Removedreact-is@16.13.1(transitive)
- Removedrehackt@0.1.0(transitive)
- Removedresponse-iterator@0.2.6(transitive)
- Removedsymbol-observable@4.0.0(transitive)
- Removedts-invariant@0.10.3(transitive)
- Removedtslib@2.8.1(transitive)
- Removedzen-observable-ts@1.2.5(transitive)