UNPKG

apollo-link-http

Version:
278 lines (248 loc) 8.06 kB
import { Observable, ApolloLink, execute } from 'apollo-link'; import gql from 'graphql-tag'; import * as fetchMock from 'fetch-mock'; import objectToQuery from 'object-to-querystring'; import { sharedHttpTest } from './sharedHttpTests'; import { HttpLink, createHttpLink } from '../httpLink'; const sampleQuery = gql` query SampleQuery { stub { id } } `; const sampleMutation = gql` mutation SampleMutation { stub { id } } `; const makeCallback = (done, body) => { return (...args) => { try { body(...args); done(); } catch (error) { done.fail(error); } }; }; describe('HttpLink', () => { describe('HttpLink-specific tests', () => { it('does not need any constructor arguments', () => { expect(() => new HttpLink()).not.toThrow(); }); const makePromise = res => new Promise((resolve, reject) => setTimeout(() => resolve(res))); const data = { data: { hello: 'world' } }; beforeEach(() => { fetchMock.restore(); fetchMock.post('begin:http://data/', makePromise(data)); fetchMock.get('begin:http://data/', makePromise(data)); }); afterEach(() => { fetchMock.restore(); }); it('constructor creates link that can call next and then complete', done => { const next = jest.fn(); const link = new HttpLink({ uri: 'http://data/' }); const observable = execute(link, { query: sampleQuery, }); observable.subscribe({ next, error: error => expect(false), complete: () => { expect(next).toHaveBeenCalledTimes(1); done(); }, }); }); it('supports using a GET request', done => { const variables = { params: 'stub' }; const extensions = { myExtension: 'foo' }; const link = createHttpLink({ uri: 'http://data/', fetchOptions: { method: 'GET' }, includeExtensions: true, }); execute(link, { query: sampleQuery, variables, extensions }).subscribe({ next: makeCallback(done, result => { const [uri, options] = fetchMock.lastCall(); const { method, body } = options; expect(body).toBeUndefined(); expect(method).toBe('GET'); expect(uri).toBe( 'http://data/?query=query%20SampleQuery%20%7B%0A%20%20stub%20%7B%0A%20%20%20%20id%0A%20%20%7D%0A%7D%0A&operationName=SampleQuery&variables=%7B%22params%22%3A%22stub%22%7D&extensions=%7B%22myExtension%22%3A%22foo%22%7D', ); }), error: error => done.fail(error), }); }); it('supports using a GET request with search and fragment', done => { const variables = { params: 'stub' }; const link = createHttpLink({ uri: 'http://data/?foo=bar#frag', fetchOptions: { method: 'GET' }, }); execute(link, { query: sampleQuery, variables }).subscribe({ next: makeCallback(done, result => { const [uri, options] = fetchMock.lastCall(); const { method, body } = options; expect(body).toBeUndefined(); expect(method).toBe('GET'); expect(uri).toBe( 'http://data/?foo=bar&query=query%20SampleQuery%20%7B%0A%20%20stub%20%7B%0A%20%20%20%20id%0A%20%20%7D%0A%7D%0A&operationName=SampleQuery&variables=%7B%22params%22%3A%22stub%22%7D#frag', ); }), error: error => done.fail(error), }); }); it('supports using a GET request on the context', done => { const variables = { params: 'stub' }; const link = createHttpLink({ uri: 'http://data/', }); execute(link, { query: sampleQuery, variables, context: { fetchOptions: { method: 'GET' }, }, }).subscribe( makeCallback(done, result => { const [uri, options] = fetchMock.lastCall(); const { method, body } = options; expect(body).toBeUndefined(); expect(method).toBe('GET'); expect(uri).toBe( 'http://data/?query=query%20SampleQuery%20%7B%0A%20%20stub%20%7B%0A%20%20%20%20id%0A%20%20%7D%0A%7D%0A&operationName=SampleQuery&variables=%7B%22params%22%3A%22stub%22%7D', ); }), ); }); it('uses GET with useGETForQueries', done => { const variables = { params: 'stub' }; const link = createHttpLink({ uri: 'http://data/', useGETForQueries: true, }); execute(link, { query: sampleQuery, variables, }).subscribe( makeCallback(done, result => { const [uri, options] = fetchMock.lastCall(); const { method, body } = options; expect(body).toBeUndefined(); expect(method).toBe('GET'); expect(uri).toBe( 'http://data/?query=query%20SampleQuery%20%7B%0A%20%20stub%20%7B%0A%20%20%20%20id%0A%20%20%7D%0A%7D%0A&operationName=SampleQuery&variables=%7B%22params%22%3A%22stub%22%7D', ); }), ); }); it('uses POST for mutations with useGETForQueries', done => { const variables = { params: 'stub' }; const link = createHttpLink({ uri: 'http://data/', useGETForQueries: true, }); execute(link, { query: sampleMutation, variables, }).subscribe( makeCallback(done, result => { const [uri, options] = fetchMock.lastCall(); const { method, body } = options; expect(body).toBeDefined(); expect(method).toBe('POST'); expect(uri).toBe('http://data/'); }), ); }); it('should add client awareness settings to request headers', done => { const variables = { params: 'stub' }; const link = createHttpLink({ uri: 'http://data/', }); const clientAwareness = { name: 'Some Client Name', version: '1.0.1', }; execute(link, { query: sampleQuery, variables, context: { clientAwareness, }, }).subscribe( makeCallback(done, result => { const [uri, options] = fetchMock.lastCall(); const { headers } = options; expect(headers['apollographql-client-name']).toBeDefined(); expect(headers['apollographql-client-name']).toEqual( clientAwareness.name, ); expect(headers['apollographql-client-version']).toBeDefined(); expect(headers['apollographql-client-version']).toEqual( clientAwareness.version, ); }), ); }); }); it("throws for GET if the variables can't be stringified", done => { const link = createHttpLink({ uri: 'http://data/', useGETForQueries: true, }); let b; const a = { b }; b = { a }; a.b = b; const variables = { a, b, }; execute(link, { query: sampleQuery, variables }).subscribe( result => { done.fail('next should have been thrown from the link'); }, makeCallback(done, e => { expect(e.message).toMatch(/Variables map is not serializable/); expect(e.parseError.message).toMatch( /Converting circular structure to JSON/, ); }), ); }); it("throws for GET if the extensions can't be stringified", done => { const link = createHttpLink({ uri: 'http://data/', useGETForQueries: true, includeExtensions: true, }); let b; const a = { b }; b = { a }; a.b = b; const extensions = { a, b, }; execute(link, { query: sampleQuery, extensions }).subscribe( result => { done.fail('next should have been thrown from the link'); }, makeCallback(done, e => { expect(e.message).toMatch(/Extensions map is not serializable/); expect(e.parseError.message).toMatch( /Converting circular structure to JSON/, ); }), ); }); sharedHttpTest('HttpLink', createHttpLink); });