Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/request / __tests__ / OneRequest.DataSources.test.ts
Size: Mime:
/**
 * @see https://github.com/apollographql/apollo-server/blob/c4d3a93e7bc8a9ffb1692c50a4f766422f30e665/packages/apollo-datasource-rest/src/__tests__/RESTDataSource.test.ts
 */
import 'jest'
import '../src/deps/polyfill'
import { fetch, Request, URL } from '../__mocks__/apollo-server-env'
import {
  ApolloError,
  AuthenticationError,
  ForbiddenError,
} from 'apollo-server-errors'
import { RESTDataSource, RequestOptions } from 'apollo-datasource-rest'
import { HTTPCache } from 'apollo-datasource-rest'
import { OneRequest } from '../src'

function toDataSourcesWithAllMethods() {
  // 'PUT',
  // const dataSource = new class extends RESTDataSource {
  //   baseURL = 'https://api.example.com'
  //   getFoo = () => this.get('foo')
  //   postFoo = () => this.post('foo')
  //   patchFoo = () => this.patch('foo')
  //   putFoo = () => this.put('foo')
  //   deleteFoo = () => this.delete('foo')
  // }()
  const deleteFoo = OneRequest.init()
    .url('https://api.example.com/foo')
    .delete()
  const getFoo = OneRequest.init()
    .url('https://api.example.com/foo')
    .get()
  const patchFoo = OneRequest.init()
    .url('https://api.example.com/foo')
    .patch()
  const postFoo = OneRequest.init()
    .url('https://api.example.com/foo')
    .post()

  const dataSources = {
    deleteFoo,
    patchFoo,
    postFoo,
    getFoo,
  }

  const dataSourceApollo = {}
  const METHOD_LIST = ['delete', 'patch', 'get', 'post']

  Object.keys(dataSources).forEach(key => {
    // should ave a better way to check if it is an adapter
    if (!dataSources[key].toApollo) {
      return
    }

    const value = dataSources[key].toApollo()

    METHOD_LIST.forEach(method => {
      const methodName = method + 'Foo'
      value[methodName] = async () => {
        const response = await value.doRequest()
        const body = response.data || response.body || response
        // console.log({ methodName, body, response })
        if (typeof body === 'string') {
          return JSON.parse(body)
        } else {
          return body
        }
      }
    })

    dataSourceApollo[key] = value
    dataSources[key] = value
  })

  return { dataSourceApollo, dataSources }
}

describe('RESTDataSource', () => {
  const store = new Map<string, string>()
  let httpCache: HTTPCache

  beforeAll(() => {
    httpCache = new HTTPCache({
      async get(key: string) {
        return store.get(key)
      },
      async set(key: string, value: string) {
        store.set(key, value)
      },
    })
  })

  beforeEach(() => {
    fetch.mockReset()
    store.clear()
  })

  describe('constructing requests', () => {
    const { dataSourceApollo } = toDataSourcesWithAllMethods()

    for (const method of ['GET', 'POST', 'PATCH', 'DELETE']) {
      const methodName = `${method.toLocaleLowerCase()}Foo`
      const dataSource = dataSourceApollo[methodName]

      it(`allows performing ${method} requests`, async () => {
        dataSource.httpCache = httpCache

        fetch.mockJSONResponseOnce({ foo: 'bar' })

        const data = await dataSource[methodName]()

        expect(data).toEqual({ foo: 'bar' })

        expect(fetch.mock.calls.length).toEqual(1)
        expect(fetch.mock.calls[0][0].method).toEqual(method)
      })
    }

    for (const method of ['GET', 'POST', 'PATCH', 'DELETE']) {
      const methodName = `${method.toLocaleLowerCase()}Foo`
      const dataSource = dataSourceApollo[methodName]
      // @todo it's logged, need to test this a lil more
      // @todo - the cache is cleared before each
      //         so will need to split this out
      it.skip(`allows caching ${method} requests`, async () => {
        dataSource.httpCache = httpCache
        fetch.mockJSONResponseOnce({ foo: 'bar' })
        const data = await dataSource[methodName]()
        expect(data).toEqual({ foo: 'bar' })
      })
    }
  })
})