diff --git a/packages/apollo-datasource-rest/src/HTTPCache.ts b/packages/apollo-datasource-rest/src/HTTPCache.ts index 1b7da5e3f96..153cf89c669 100644 --- a/packages/apollo-datasource-rest/src/HTTPCache.ts +++ b/packages/apollo-datasource-rest/src/HTTPCache.ts @@ -6,7 +6,10 @@ import { KeyValueCache, InMemoryLRUCache } from 'apollo-server-caching'; import { CacheOptions } from './RESTDataSource'; export class HTTPCache { - constructor(private keyValueCache: KeyValueCache = new InMemoryLRUCache()) {} + constructor( + private keyValueCache: KeyValueCache = new InMemoryLRUCache(), + private httpFetch: typeof fetch = fetch, + ) {} async fetch( request: Request, @@ -21,7 +24,7 @@ export class HTTPCache { const entry = await this.keyValueCache.get(`httpcache:${cacheKey}`); if (!entry) { - const response = await fetch(request); + const response = await this.httpFetch(request); const policy = new CachePolicy( policyRequestFrom(request), @@ -61,7 +64,7 @@ export class HTTPCache { const revalidationRequest = new Request(request, { headers: revalidationHeaders, }); - const revalidationResponse = await fetch(revalidationRequest); + const revalidationResponse = await this.httpFetch(revalidationRequest); const { policy: revalidatedPolicy, modified } = policy.revalidatedPolicy( policyRequestFrom(revalidationRequest), diff --git a/packages/apollo-datasource-rest/src/RESTDataSource.ts b/packages/apollo-datasource-rest/src/RESTDataSource.ts index 59b068768e6..aa95f80f9dc 100644 --- a/packages/apollo-datasource-rest/src/RESTDataSource.ts +++ b/packages/apollo-datasource-rest/src/RESTDataSource.ts @@ -7,6 +7,7 @@ import { URL, URLSearchParams, URLSearchParamsInit, + fetch, } from 'apollo-server-env'; import { DataSource, DataSourceConfig } from 'apollo-datasource'; @@ -48,9 +49,13 @@ export abstract class RESTDataSource extends DataSource { context!: TContext; memoizedResults = new Map>(); + constructor(private httpFetch?: typeof fetch) { + super(); + } + initialize(config: DataSourceConfig): void { this.context = config.context; - this.httpCache = new HTTPCache(config.cache); + this.httpCache = new HTTPCache(config.cache, this.httpFetch); } baseURL?: string; diff --git a/packages/apollo-datasource-rest/src/__tests__/HTTPCache.test.ts b/packages/apollo-datasource-rest/src/__tests__/HTTPCache.test.ts index 3935a667861..72849304ecb 100644 --- a/packages/apollo-datasource-rest/src/__tests__/HTTPCache.test.ts +++ b/packages/apollo-datasource-rest/src/__tests__/HTTPCache.test.ts @@ -452,4 +452,18 @@ describe('HTTPCache', () => { expect(await response2.json()).toEqual({ name: 'Alan Turing' }); expect(response2.headers.get('Age')).toEqual('10'); }); + + it('fetches a response from the origin with a custom fetch function', async () => { + fetch.mockJSONResponseOnce({ name: 'Ada Lovelace' }); + + const customFetch = jest.fn(fetch); + const customHttpCache = new HTTPCache(store as any, customFetch); + + const response = await customHttpCache.fetch( + new Request('https://api.example.com/people/1'), + ); + + expect(customFetch.mock.calls.length).toEqual(1); + expect(await response.json()).toEqual({ name: 'Ada Lovelace' }); + }); });