test('creates get action creator from thunk that does not call thunk if page is already loaded', (assert) => {
  const done = assert.async()
  const mockStore = createMockStore({
    things: {
      currentPage: 1,
      pages: { 1: { item: [], loadState: LoadStates.LOADED } }
    },
  })
  const dispatchSpy = sinon.spy(mockStore, 'dispatch')
  const thunk = () => (resolve, _reject) => resolve({ data: ['item1'] })
  const { actionCreators } = createPaginationActions('things', thunk)
  actionCreators.getThings()(mockStore.dispatch, mockStore.getState)
  setTimeout(() => {
    equal(dispatchSpy.callCount, 0)
    dispatchSpy.restore()
    done()
  })
})
test('creates get action creator from thunk that calls success', (assert) => {
  const done = assert.async()
  const mockStore = createMockStore({
    things: {
      currentPage: 1,
      pages: { 1: { item: [], loadState: LoadStates.NOT_LOADED } }
    },
  })
  const dispatchSpy = sinon.spy(mockStore, 'dispatch')
  const thunk = () => (resolve, _reject) => resolve({ data: ['item1'] })
  const { actionCreators } = createPaginationActions('things', thunk)
  actionCreators.getThings({ page: 5 })(mockStore.dispatch, mockStore.getState)
  setTimeout(() => {
    equal(dispatchSpy.callCount, 2)
    deepEqual(dispatchSpy.secondCall.args, [{ type: 'GET_THINGS_SUCCESS', payload: { page: 5, data: ['item1'] } }])
    dispatchSpy.restore()
    done()
  })
})
test('creates get action creator from thunk that selects the page if select is true', (assert) => {
  const done = assert.async()
  const mockStore = createMockStore({
    things: {
      currentPage: 1,
      pages: { 1: { item: [], loadState: LoadStates.LOADED } }
    },
  })
  const dispatchSpy = sinon.spy(mockStore, 'dispatch')
  const thunk = () => (resolve, _reject) => resolve({ data: ['item1'] })
  const { actionCreators } = createPaginationActions('things', thunk)
  actionCreators.getThings({ select: true, page: 5 })(mockStore.dispatch, mockStore.getState)
  setTimeout(() => {
    equal(dispatchSpy.callCount, 3)
    deepEqual(dispatchSpy.firstCall.args, [{ type: 'SELECT_THINGS_PAGE', payload: { page: 5 } }])
    dispatchSpy.restore()
    done()
  })
})
test('creates get action creator from thunk that calls success with lastPage is provided in response link header', (assert) => {
  const done = assert.async()
  const mockStore = createMockStore({
    things: {
      currentPage: 1,
      pages: { 1: { item: [], loadState: LoadStates.NOT_LOADED } }
    },
  })
  const dispatchSpy = sinon.spy(mockStore, 'dispatch')
  const thunk = () => (resolve, _reject) => resolve({ data: ['item1'], headers: { link: '<http://canvas.example.com/api/v1/someendpoint&page=5&per_page=50>; rel="last"' } })
  const { actionCreators } = createPaginationActions('things', thunk)
  actionCreators.getThings()(mockStore.dispatch, mockStore.getState)
  setTimeout(() => {
    equal(dispatchSpy.callCount, 2)
    deepEqual(dispatchSpy.secondCall.args, [{ type: 'GET_THINGS_SUCCESS', payload: { page: 1, data: ['item1'], lastPage: 5 } }])
    dispatchSpy.restore()
    done()
  })
})
test('can get all pagination results under a single set of dispatches', (assert) => {
  const done = assert.async()
  const mockStore = createMockStore({
    things: {
      currentPage: 1,
      pages: { 1: { item: [], loadState: LoadStates.NOT_LOADED } }
    },
  })
  const dispatchSpy = sinon.spy(mockStore, 'dispatch')

  const mockResult = {
    data: ['item1'],
    headers: {
      link: '<http://canvas.example.com/api/v1/someendpoint&page=5&per_page=50>; rel="last"'
    }
  }
  const thunk = () => new Promise((resolve, _reject) => resolve(mockResult))
  const { actionCreators } = createPaginationActions('things', thunk, {totalCount: 250, fetchAll: true })
  actionCreators.getThings()(mockStore.dispatch, mockStore.getState)
  setTimeout(() => {
    equal(dispatchSpy.callCount, 2)
    deepEqual(dispatchSpy.firstCall.args, [{ type: 'GET_THINGS_START', payload: { page: 1 } }])

    // Should have item1 5 times, as the link header indicated there were 5
    // pages that needed to be gathered
    const expectedResults = {
      type: 'GET_THINGS_SUCCESS',
      payload: {
        data: [ "item1", "item1", "item1", "item1", "item1" ],
        lastPage: 1,
        page: 1
      }
    }
    deepEqual(dispatchSpy.secondCall.args, [expectedResults])
    dispatchSpy.restore()
    done()
  }, 750)
})
test('creates get action creator', () => {
  const { actionCreators } = createPaginationActions('things')
  equal(typeof actionCreators.getThings, 'function')
})
test('creates proper actionTypes', () => {
  const { actionTypes } = createPaginationActions('things')
  deepEqual(actionTypes, ['SELECT_THINGS_PAGE',  'GET_THINGS_START', 'GET_THINGS_SUCCESS', 'GET_THINGS_FAIL', 'CLEAR_THINGS_PAGE'])
})