diff --git a/fetch-mock.typings.d.ts b/fetch-mock.typings.d.ts index e046baed11d..6f6210daf5c 100644 --- a/fetch-mock.typings.d.ts +++ b/fetch-mock.typings.d.ts @@ -1,4 +1,3 @@ - /* FETCH-MOCK */ // This is a slightly modified version of https://www.npmjs.com/package/@types/fetch-mock // We can't use the package directly because it depends on @types/whatwg-fetch @@ -23,7 +22,7 @@ declare namespace FetchMock { * @param url * @param opts */ - type MockMatcherFunction = (url: string, opts: MockRequest) => boolean + type MockMatcherFunction = (url: string, opts: MockRequest) => boolean; /** * Mock matcher. Can be one of following: * string: Either @@ -43,30 +42,30 @@ declare namespace FetchMock { * Mock response object */ interface MockResponseObject { - /** + /** * Set the response body */ - body?: string | {}; - /** + body?: string | {}; + /** * Set the response status * @default 200 */ - status?: number; - /** + status?: number; + /** * Set the response headers. */ - headers?: { [key: string]: string }; - /** + headers?: { [key: string]: string }; + /** * If this property is present then a Promise rejected with the value of throws is returned */ - throws?: boolean; - /** + throws?: boolean; + /** * This property determines whether or not the request body should be JSON.stringified before being sent * @default true */ - sendAsJson?: boolean; + sendAsJson?: boolean; } /** * Response: A Response instance - will be used unaltered @@ -78,11 +77,17 @@ declare namespace FetchMock { * Function(url, opts): A function that is passed the url and opts fetch() is called with and that returns any of the responses listed above */ - type MockResponse = Response | Promise - | number | Promise - | string | Promise - | Object | Promise - | MockResponseObject | Promise; + type MockResponse = + | Response + | Promise + | number + | Promise + | string + | Promise + | Object + | Promise + | MockResponseObject + | Promise; /** * Mock response function * @param url @@ -94,7 +99,7 @@ declare namespace FetchMock { * Mock options object */ interface MockOptions { - /** + /** * A unique string naming the route. Used to subsequently retrieve references to the calls, grouped by name. * @default matcher.toString() @@ -103,58 +108,61 @@ declare namespace FetchMock { (because names are optional, auto-generated ones may legitimately clash) */ - name?: string; - /** + name?: string; + /** * http method to match */ - method?: string; - /** + method?: string; + /** * as specified above */ - matcher?: MockMatcher; - /** + matcher?: MockMatcher; + /** * as specified above */ - response?: MockResponse | MockResponseFunction; + response?: MockResponse | MockResponseFunction; } type MockCall = [string, MockRequest]; interface MatchedRoutes { - matched: Array; - unmatched: Array; + matched: Array; + unmatched: Array; } interface MockOptionsMethodGet extends MockOptions { - method: 'GET' + method: 'GET'; } interface MockOptionsMethodPost extends MockOptions { - method: 'POST' + method: 'POST'; } interface MockOptionsMethodPut extends MockOptions { - method: 'PUT' + method: 'PUT'; } interface MockOptionsMethodDelete extends MockOptions { - method: 'DELETE' + method: 'DELETE'; } interface MockOptionsMethodHead extends MockOptions { - method: 'HEAD' + method: 'HEAD'; } export interface FetchMockStatic { - /** + /** * Replaces fetch() with a stub which records its calls, grouped by route, and optionally returns a mocked Response object or passes the call through to fetch(). Calls to .mock() can be chained. * @param matcher Condition for selecting which requests to mock * @param response Configures the http response returned by the mock */ - mock(matcher: MockMatcher, response: MockResponse | MockResponseFunction): this; - /** + mock( + matcher: MockMatcher, + response: MockResponse | MockResponseFunction, + ): this; + /** * Replaces fetch() with a stub which records its calls, grouped by route, and optionally returns a mocked Response object or passes the call through to fetch(). Calls to .mock() can be chained. @@ -162,15 +170,19 @@ declare namespace FetchMock { * @param response Configures the http response returned by the mock * @param options Additional properties defining the route to mock */ - mock(matcher: MockMatcher, response: MockResponse | MockResponseFunction, options: MockOptions): this; - /** + mock( + matcher: MockMatcher, + response: MockResponse | MockResponseFunction, + options: MockOptions, + ): this; + /** * Replaces fetch() with a stub which records its calls, grouped by route, and optionally returns a mocked Response object or passes the call through to fetch(). Calls to .mock() can be chained. * @param options The route to mock */ - mock(options: MockOptions): this; - /** + mock(options: MockOptions): this; + /** * Replaces fetch() with a stub which records its calls, grouped by route, and optionally returns a mocked Response object or passes the call through to fetch(). Shorthand for mock() restricted to the GET @@ -179,8 +191,12 @@ declare namespace FetchMock { * @param response Configures the http response returned by the mock * @param [options] Additional properties defining the route to mock */ - get(matcher: MockMatcher, reponse: MockResponse | MockResponseFunction, options?: MockOptionsMethodGet): this; - /** + get( + matcher: MockMatcher, + reponse: MockResponse | MockResponseFunction, + options?: MockOptionsMethodGet, + ): this; + /** * Replaces fetch() with a stub which records its calls, grouped by route, and optionally returns a mocked Response object or passes the call through to fetch(). Shorthand for mock() restricted to the POST @@ -189,8 +205,12 @@ declare namespace FetchMock { * @param response Configures the http response returned by the mock * @param [options] Additional properties defining the route to mock */ - post(matcher: MockMatcher, reponse: MockResponse | MockResponseFunction, options?: MockOptionsMethodPost): this; - /** + post( + matcher: MockMatcher, + reponse: MockResponse | MockResponseFunction, + options?: MockOptionsMethodPost, + ): this; + /** * Replaces fetch() with a stub which records its calls, grouped by route, and optionally returns a mocked Response object or passes the call through to fetch(). Shorthand for mock() restricted to the PUT @@ -199,8 +219,12 @@ declare namespace FetchMock { * @param response Configures the http response returned by the mock * @param [options] Additional properties defining the route to mock */ - put(matcher: MockMatcher, reponse: MockResponse | MockResponseFunction, options?: MockOptionsMethodPut): this; - /** + put( + matcher: MockMatcher, + reponse: MockResponse | MockResponseFunction, + options?: MockOptionsMethodPut, + ): this; + /** * Replaces fetch() with a stub which records its calls, grouped by route, and optionally returns a mocked Response object or passes the call through to fetch(). Shorthand for mock() restricted to the @@ -209,8 +233,12 @@ declare namespace FetchMock { * @param response Configures the http response returned by the mock * @param [options] Additional properties defining the route to mock */ - delete(matcher: MockMatcher, reponse: MockResponse | MockResponseFunction, options?: MockOptionsMethodDelete): this; - /** + delete( + matcher: MockMatcher, + reponse: MockResponse | MockResponseFunction, + options?: MockOptionsMethodDelete, + ): this; + /** * Replaces fetch() with a stub which records its calls, grouped by route, and optionally returns a mocked Response object or passes the call through to fetch(). Shorthand for mock() restricted to the HEAD @@ -219,68 +247,80 @@ declare namespace FetchMock { * @param response Configures the http response returned by the mock * @param [options] Additional properties defining the route to mock */ - head(matcher: MockMatcher, reponse: MockResponse | MockResponseFunction, options?: MockOptionsMethodHead): this; - /** + head( + matcher: MockMatcher, + reponse: MockResponse | MockResponseFunction, + options?: MockOptionsMethodHead, + ): this; + /** * Chainable method that restores fetch() to its unstubbed state and clears all data recorded for its calls. */ - restore(): this; - /** + restore(): this; + /** * Chainable method that clears all data recorded for fetch()'s calls */ - reset(): this; - /** + reset(): this; + /** * Returns all calls to fetch, grouped by whether fetch-mock matched them or not. */ - calls(): MatchedRoutes; - /** + calls(): MatchedRoutes; + /** * Returns all calls to fetch matching matcherName. */ - calls(matcherName?: string): Array; - /** + calls(matcherName?: string): Array; + /** * Returns a Boolean indicating whether fetch was called and a route was matched. */ - called(): boolean; - /** + called(): boolean; + /** * Returns a Boolean indicating whether fetch was called and a route named matcherName was matched. */ - called(matcherName?: string): boolean; - /** + called(matcherName?: string): boolean; + /** * Returns the arguments for the last matched call to fetch */ - lastCall(): MockCall; - /** + lastCall(): MockCall; + /** * Returns the arguments for the last call to fetch matching matcherName */ - lastCall(matcherName?: string): MockCall; - /** + lastCall(matcherName?: string): MockCall; + /** * Returns the url for the last matched call to fetch */ - lastUrl(): string; - /** + lastUrl(): string; + /** * Returns the url for the last call to fetch matching matcherName */ - lastUrl(matcherName?: string): string; - /** + lastUrl(matcherName?: string): string; + /** * Returns the options for the last matched call to fetch */ - lastOptions(): MockRequest; - /** + lastOptions(): MockRequest; + /** * Returns the options for the last call to fetch matching matcherName */ - lastOptions(matcherName?: string): MockRequest; - /** + lastOptions(matcherName?: string): MockRequest; + /** * Set some global config options, which include * sendAsJson [default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable for each call but for some scenarios, e.g. when dealing with a lot of array buffers, it can be useful to default to `false` */ - configure(opts: Object): void; + configure(opts: Object): void; + /** + * Configure the fetch implementation to be used + */ + setImplementations(implementations: Object): void; + /** + * Return a sandbox + */ + sandbox(): FetchMockStatic; } } diff --git a/fetch-ponyfill.typings.d.ts b/fetch-ponyfill.typings.d.ts new file mode 100644 index 00000000000..2f39686ef6e --- /dev/null +++ b/fetch-ponyfill.typings.d.ts @@ -0,0 +1,8 @@ +// Type definitions for fetch-ponyfill 4.1.0 +// Project: https://github.com/qubyte/fetch-ponyfill + +declare function fetchPonyfill(options?: any): any + +declare module 'fetch-ponyfill' { + export = fetchPonyfill; +} diff --git a/package.json b/package.json index 68859fb2bf0..0ca48a9c29e 100644 --- a/package.json +++ b/package.json @@ -73,12 +73,12 @@ "license": "MIT", "dependencies": { "apollo-link-core": "^0.2.0", + "fetch-ponyfill": "^4.1.0", "graphql": "^0.10.0", "graphql-anywhere": "^3.0.1", "graphql-tag": "^2.0.0", "redux": "^3.4.0", - "symbol-observable": "^1.0.2", - "whatwg-fetch": "^2.0.0" + "symbol-observable": "^1.0.2" }, "devDependencies": { "@types/benchmark": "1.0.30", diff --git a/src/transport/batchedNetworkInterface.ts b/src/transport/batchedNetworkInterface.ts index 22ecbf6471c..f5d478b398d 100644 --- a/src/transport/batchedNetworkInterface.ts +++ b/src/transport/batchedNetworkInterface.ts @@ -1,7 +1,5 @@ import { ExecutionResult } from 'graphql'; -import 'whatwg-fetch'; - import { BaseNetworkInterface, HTTPNetworkInterface, @@ -43,13 +41,15 @@ export class HTTPBatchedNetworkInterface extends BaseNetworkInterface { batchInterval = 10, batchMax = 0, fetchOpts, + fetch = undefined, }: { uri: string; batchInterval?: number; batchMax?: number; fetchOpts: RequestInit; + fetch?: any; }) { - super(uri, fetchOpts); + super(uri, fetchOpts, fetch); if (typeof batchInterval !== 'number') { throw new Error(`batchInterval must be a number, got ${batchInterval}`); @@ -236,7 +236,7 @@ export class HTTPBatchedNetworkInterface extends BaseNetworkInterface { return printRequest(request); }); - return fetch(this._uri, { + return this._fetch(this._uri, { ...this._opts, body: JSON.stringify(printedRequests), method: 'POST', @@ -255,6 +255,7 @@ export interface BatchingNetworkInterfaceOptions { batchInterval?: number; batchMax?: number; opts?: RequestInit; + fetch?: any; } export function createBatchingNetworkInterface( @@ -270,5 +271,6 @@ export function createBatchingNetworkInterface( batchInterval: options.batchInterval, batchMax: options.batchMax, fetchOpts: options.opts || {}, + fetch: options.fetch, }); } diff --git a/src/transport/networkInterface.ts b/src/transport/networkInterface.ts index 7c7819b667c..9d074b5922c 100644 --- a/src/transport/networkInterface.ts +++ b/src/transport/networkInterface.ts @@ -1,5 +1,3 @@ -import 'whatwg-fetch'; - import { ExecutionResult, DocumentNode } from 'graphql'; import { print } from 'graphql/language/printer'; @@ -12,6 +10,8 @@ import { removeConnectionDirectiveFromDocument } from '../queries/queryTransform import { Observable } from '../util/Observable'; +import fetchPonyfill = require('fetch-ponyfill'); + /** * This is an interface that describes an GraphQL document to be sent * to the server. @@ -100,8 +100,13 @@ export class BaseNetworkInterface implements NetworkInterface { public _afterwares: AfterwareInterface[] | BatchAfterwareInterface[]; public _uri: string; public _opts: RequestInit; + public _fetch: any; - constructor(uri: string | undefined, opts: RequestInit = {}) { + constructor( + uri: string | undefined, + opts: RequestInit = {}, + fetch: any | undefined, + ) { if (!uri) { throw new Error('A remote endpoint is required for a network layer'); } @@ -112,6 +117,7 @@ export class BaseNetworkInterface implements NetworkInterface { this._uri = uri; this._opts = { ...opts }; + this._fetch = fetch || fetchPonyfill(); this._middlewares = []; this._afterwares = []; @@ -184,7 +190,7 @@ export class HTTPFetchNetworkInterface extends BaseNetworkInterface { request, options, }: RequestAndOptions): Promise { - return fetch(this._uri, { + return this._fetch(this._uri, { ...this._opts, body: JSON.stringify(printRequest(request)), method: 'POST', @@ -277,6 +283,7 @@ export class HTTPFetchNetworkInterface extends BaseNetworkInterface { export interface NetworkInterfaceOptions { uri?: string; opts?: RequestInit; + fetch?: any; } export function createNetworkInterface( @@ -291,6 +298,7 @@ export function createNetworkInterface( let uri: string | undefined; let opts: RequestInit | undefined; + let fetch: any | undefined; // We want to change the API in the future so that you just pass all of the options as one // argument, so even though the internals work with two arguments we're warning here. @@ -299,9 +307,11 @@ export function createNetworkInterface( as of Apollo Client 0.5. Please pass it as the "uri" property of the network interface options.`); opts = secondArgOpts.opts; uri = uriOrInterfaceOpts; + fetch = secondArgOpts.fetch; } else { opts = uriOrInterfaceOpts.opts; uri = uriOrInterfaceOpts.uri; + fetch = uriOrInterfaceOpts.fetch; } - return new HTTPFetchNetworkInterface(uri, opts); + return new HTTPFetchNetworkInterface(uri, opts, fetch); } diff --git a/test/batchedNetworkInterface.ts b/test/batchedNetworkInterface.ts index 75fd2456e0d..d3bc98b5367 100644 --- a/test/batchedNetworkInterface.ts +++ b/test/batchedNetworkInterface.ts @@ -17,10 +17,6 @@ import { ExecutionResult } from 'graphql'; import gql from 'graphql-tag'; -import 'whatwg-fetch'; - -declare var fetch: any; - describe('HTTPBatchedNetworkInterface', () => { // Helper method that tests a roundtrip given a particular set of requests to the // batched network interface and the @@ -41,14 +37,6 @@ describe('HTTPBatchedNetworkInterface', () => { opts?: RequestInit; }) => { const url = 'http://fake.com/graphql'; - const batchedNetworkInterface = new HTTPBatchedNetworkInterface({ - uri: url, - batchInterval: 10, - fetchOpts: opts, - }); - - batchedNetworkInterface.use(middlewares); - batchedNetworkInterface.useAfter(afterwares); const printedRequests: Array = []; const resultList: Array = []; @@ -57,7 +45,7 @@ describe('HTTPBatchedNetworkInterface', () => { resultList.push(result); }); - fetch = + const fetch = fetchFunc || createMockFetch({ url, @@ -75,6 +63,16 @@ describe('HTTPBatchedNetworkInterface', () => { result: createMockedIResponse(resultList), }); + const batchedNetworkInterface = new HTTPBatchedNetworkInterface({ + uri: url, + batchInterval: 10, + fetchOpts: opts, + fetch, + }); + + batchedNetworkInterface.use(middlewares); + batchedNetworkInterface.useAfter(afterwares); + return batchedNetworkInterface .batchQuery(requestResultPairs.map(({ request }) => request)) .then(results => { @@ -459,18 +457,13 @@ describe('HTTPBatchedNetworkInterface', () => { `; const url = 'http://fake.com/graphql'; - const batchedNetworkInterface = new HTTPBatchedNetworkInterface({ - uri: url, - batchInterval: 10, - fetchOpts: {}, - }); const printedRequests: Array = [ printRequest({ query: authorQuery }), ]; const resultList: Array = [authorResult]; - fetch = createMockFetch({ + const fetch = createMockFetch({ url, opts: { body: JSON.stringify(printedRequests), @@ -483,6 +476,13 @@ describe('HTTPBatchedNetworkInterface', () => { result: createMockedIResponse(resultList), }); + const batchedNetworkInterface = new HTTPBatchedNetworkInterface({ + uri: url, + batchInterval: 10, + fetchOpts: {}, + fetch, + }); + return batchedNetworkInterface .batchQuery([{ query: authorQueryWithConnection }]) .then(results => { diff --git a/test/client.ts b/test/client.ts index 6dd374f609a..951083ea3e4 100644 --- a/test/client.ts +++ b/test/client.ts @@ -1,7 +1,6 @@ import * as chai from 'chai'; const { assert } = chai; import * as sinon from 'sinon'; -import * as fetchMock from 'fetch-mock'; import ApolloClient, { printAST } from '../src'; @@ -72,8 +71,6 @@ import { cloneDeep, assign, isEqual } from 'lodash'; import { ApolloLink, Observable } from 'apollo-link-core'; -declare var fetch: any; - // make it easy to assert with promises chai.use(chaiAsPromised); @@ -2348,8 +2345,7 @@ describe('client', () => { }, }; const url = 'http://not-a-real-url.com'; - const oldFetch = fetch; - fetch = createMockFetch({ + const fetch = createMockFetch({ url, opts: { body: JSON.stringify([ @@ -2372,6 +2368,7 @@ describe('client', () => { uri: 'http://not-a-real-url.com', batchInterval: 5, opts: {}, + fetch, }); Promise.all([ networkInterface.query({ query: firstQuery }), @@ -2382,7 +2379,6 @@ describe('client', () => { firstResult, secondResult, ]); - fetch = oldFetch; done(); }) .catch(e => { @@ -2416,8 +2412,7 @@ describe('client', () => { } `; const url = 'http://not-a-real-url.com'; - const oldFetch = fetch; - fetch = createMockFetch({ + const fetch = createMockFetch({ url, opts: { body: JSON.stringify([ @@ -2440,6 +2435,7 @@ describe('client', () => { uri: 'http://not-a-real-url.com', batchInterval: 5, opts: {}, + fetch, }); Promise.all([ networkInterface.query({ query: firstQuery }), @@ -2453,7 +2449,6 @@ describe('client', () => { e.message, 'BatchingNetworkInterface: server response is not an array', ); - fetch = oldFetch; done(); }); }); @@ -2491,8 +2486,7 @@ describe('client', () => { }, }; const url = 'http://not-a-real-url.com'; - const oldFetch = fetch; - fetch = createMockFetch( + const fetch = createMockFetch( { url, opts: { @@ -2530,6 +2524,7 @@ describe('client', () => { uri: 'http://not-a-real-url.com', batchInterval: 5, opts: {}, + fetch, }); Promise.all([ networkInterface.query({ query: firstQuery }), @@ -2545,7 +2540,6 @@ describe('client', () => { firstResult, secondResult, ]); - fetch = oldFetch; done(); }) .catch(e => { @@ -2585,15 +2579,7 @@ describe('client', () => { const url = 'http://not-a-real-url.com'; - const networkInterface = createBatchingNetworkInterface({ - uri: url, - batchInterval: 5, - batchMax: 2, - opts: {}, - }); - - const oldFetch = fetch; - fetch = createMockFetch( + const fetch = createMockFetch( { url, opts: { @@ -2638,6 +2624,14 @@ describe('client', () => { }, ); + const networkInterface = createBatchingNetworkInterface({ + uri: url, + batchInterval: 5, + batchMax: 2, + opts: {}, + fetch, + }); + Promise.all([ networkInterface.query({ query: authorQuery }), networkInterface.query({ query: personQuery }), @@ -2661,7 +2655,6 @@ describe('client', () => { personResult, authorResult, ]); - fetch = oldFetch; done(); }) .catch(e => { @@ -2701,14 +2694,7 @@ describe('client', () => { const url = 'http://not-a-real-url.com'; - const networkInterface = createBatchingNetworkInterface({ - uri: url, - batchInterval: 5, - opts: {}, - }); - - const oldFetch = fetch; - fetch = createMockFetch({ + const fetch = createMockFetch({ url, opts: { body: JSON.stringify([ @@ -2733,6 +2719,13 @@ describe('client', () => { ]), }); + const networkInterface = createBatchingNetworkInterface({ + uri: url, + batchInterval: 5, + opts: {}, + fetch, + }); + Promise.all([ networkInterface.query({ query: authorQuery }), networkInterface.query({ query: personQuery }), @@ -2756,7 +2749,6 @@ describe('client', () => { personResult, authorResult, ]); - fetch = oldFetch; done(); }) .catch(e => { diff --git a/test/mocks/mockFetch.ts b/test/mocks/mockFetch.ts index 3b13f427b7a..da5d5f9e9f6 100644 --- a/test/mocks/mockFetch.ts +++ b/test/mocks/mockFetch.ts @@ -1,4 +1,6 @@ -import 'whatwg-fetch'; +import fetchPonyfill = require('fetch-ponyfill'); + +const { fetch } = fetchPonyfill(); // This is an implementation of a mocked window.fetch implementation similar in // structure to the MockedNetworkInterface. diff --git a/test/networkInterface.ts b/test/networkInterface.ts index cd445ff5980..be8eece8a8c 100644 --- a/test/networkInterface.ts +++ b/test/networkInterface.ts @@ -2,7 +2,12 @@ import * as chai from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import { assign, isEqual } from 'lodash'; -import * as fetchMock from 'fetch-mock'; +import * as fetchMockModule from 'fetch-mock'; + +import fetchPonyfill = require('fetch-ponyfill'); + +const fetchMock = fetchMockModule.sandbox(); +fetchMock.setImplementations(fetchPonyfill()); // make it easy to assert with promises chai.use(chaiAsPromised); @@ -257,7 +262,7 @@ describe('network interface', () => { it('should alter the request variables', () => { const testWare1 = TestWare([{ key: 'personNum', val: 1 }]); - const swapi = createNetworkInterface({ uri: swapiUrl }); + const swapi = createNetworkInterface({ uri: swapiUrl, fetch: fetchMock }); swapi.use([testWare1]); // this is a stub for the end user client api const simpleRequest = { @@ -275,7 +280,7 @@ describe('network interface', () => { it('should alter the options but not overwrite defaults', () => { const testWare1 = TestWare([], [{ key: 'planet', val: 'mars' }]); - const swapi = createNetworkInterface({ uri: swapiUrl }); + const swapi = createNetworkInterface({ uri: swapiUrl, fetch: fetchMock }); swapi.use([testWare1]); // this is a stub for the end user client api const simpleRequest = { @@ -299,6 +304,7 @@ describe('network interface', () => { const swapi = createNetworkInterface({ uri: 'http://graphql-swapi.test/', + fetch: fetchMock, }); swapi.use([testWare1]); const simpleRequest = { @@ -327,6 +333,7 @@ describe('network interface', () => { const swapi = createNetworkInterface({ uri: 'http://graphql-swapi.test/', + fetch: fetchMock, }); swapi.use([testWare1, testWare2]); // this is a stub for the end user client api @@ -346,7 +353,7 @@ describe('network interface', () => { const testWare1 = TestWare([{ key: 'personNum', val: 1 }]); const testWare2 = TestWare([{ key: 'filmNum', val: 1 }]); - const swapi = createNetworkInterface({ uri: swapiUrl }); + const swapi = createNetworkInterface({ uri: swapiUrl, fetch: fetchMock }); swapi.use([testWare1]).use([testWare2]); const simpleRequest = { query: complexQueryWithTwoVars, @@ -373,7 +380,10 @@ describe('network interface', () => { describe('afterware', () => { it('should return errors thrown in afterwares', () => { - const networkInterface = createNetworkInterface({ uri: swapiUrl }); + const networkInterface = createNetworkInterface({ + uri: swapiUrl, + fetch: fetchMock, + }); networkInterface.useAfter([ { applyAfterware() { @@ -459,7 +469,7 @@ describe('network interface', () => { }; it('should fetch remote data', () => { - const swapi = createNetworkInterface({ uri: swapiUrl }); + const swapi = createNetworkInterface({ uri: swapiUrl, fetch: fetchMock }); // this is a stub for the end user client api const simpleRequest = { @@ -483,6 +493,7 @@ describe('network interface', () => { it('should throw an error with the response when request is forbidden', () => { const unauthorizedInterface = createNetworkInterface({ uri: unauthorizedUrl, + fetch: fetchMock, }); return unauthorizedInterface.query(doomedToFail).catch(err => { @@ -498,6 +509,7 @@ describe('network interface', () => { it('should throw an error with the response when service is unavailable', () => { const unauthorizedInterface = createNetworkInterface({ uri: serviceUnavailableUrl, + fetch: fetchMock, }); return unauthorizedInterface.query(doomedToFail).catch(err => { @@ -513,7 +525,7 @@ describe('network interface', () => { describe('transforming queries', () => { it('should remove the @connection directive', () => { - const swapi = createNetworkInterface({ uri: swapiUrl }); + const swapi = createNetworkInterface({ uri: swapiUrl, fetch: fetchMock }); const simpleRequestWithConnection = { query: simpleQueryWithConnection, @@ -528,7 +540,7 @@ describe('network interface', () => { }); it('should remove the @connection directive even with no key but warn the user', () => { - const swapi = createNetworkInterface({ uri: swapiUrl }); + const swapi = createNetworkInterface({ uri: swapiUrl, fetch: fetchMock }); const simpleRequestWithConnectionButNoKey = { query: simpleQueryWithConnectionButNoKey, diff --git a/test/tests.ts b/test/tests.ts index 9048229ddfe..391d9d08b7e 100644 --- a/test/tests.ts +++ b/test/tests.ts @@ -6,9 +6,8 @@ /// /// -// ensure support for fetch and promise +// ensure support for promise import 'es6-promise'; -import 'isomorphic-fetch'; import { QueryManager } from '../src/core/QueryManager'; diff --git a/tsconfig.json b/tsconfig.json index 68d5e8312d5..319fd8806f6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,6 +19,7 @@ "node_modules/typescript/lib/lib.es2015.d.ts", "node_modules/typescript/lib/lib.dom.d.ts", "typings.d.ts", + "fetch-ponyfill.typings.d.ts", "fetch-mock.typings.d.ts", "src/index.ts", "test/tests.ts",