import { expect } from 'chai'
import { fromJS } from 'immutable'

import persistedStorageMiddlewareCreator from '../persistedStorageMiddleware'

import {
  ACTIVE_QUESTION,
  CACHED_SESSION_ID,
  ACTIVE_QUIZ_SESSION_CHANGE,
  BACKTRACKING_NEXT_QUESTION,
  PREVIOUS_QUESTION,
  SET_CURRENT_SESSION_ITEM_POSITION
} from '@instructure/quiz-common/lib/constants'

describe('persistedStorageMiddleware', () => {
  const stubNext = sinon.stub()

  const testNextAction = function (dispatch, action) {
    it('returns the result of next(action)', () => {
      stubNext.resetHistory()
      stubNext.returns(action)
      const returned = dispatch(action)
      expect(stubNext.calledWith(action)).to.be.true()
      expect(returned).to.be.equal(action)
    })
  }

  context('storing in local storage', () => {
    const setStub = sinon.stub()
    const fakeLocalStore = {
      enabled: true,
      set: setStub
    }
    const currentSessionItemPosition = 22
    const activeQuizSessionId = '44'
    const fakeAppStore = {
      getState: () => fromJS({
        taking: { currentSessionItemPosition },
        quizSessions: { activeQuizSessionId }
      })
    }
    const persistedStorageMiddleware = persistedStorageMiddlewareCreator(void 0, fakeLocalStore)
    const dispatch = persistedStorageMiddleware(fakeAppStore)(stubNext)

    context('action needs to persistTakingInfo', () => {
      const checkTakingDataPersisted = (type) => {
        context(`action of type: ${type}`, () => {
          it('saves activeQuizSessionId', () => {
            const action = { type }
            setStub.resetHistory()
            dispatch(action)
            expect(
              setStub.calledWith(CACHED_SESSION_ID, activeQuizSessionId)
            ).to.be.true()
          })

          it('saves currentSessionItemPosition', () => {
            const action = { type }
            setStub.resetHistory()
            dispatch(action)
            expect(
              setStub.calledWith(ACTIVE_QUESTION, currentSessionItemPosition)
            ).to.be.true()
          })
        })
      }

      const actionTypes = [
        ACTIVE_QUIZ_SESSION_CHANGE,
        BACKTRACKING_NEXT_QUESTION,
        PREVIOUS_QUESTION,
        SET_CURRENT_SESSION_ITEM_POSITION
      ]

      actionTypes.forEach(checkTakingDataPersisted)
    })
  })

  context('storage is not enabled', () => {
    const fakeSessionStore = {
      enabled: false
    }
    const fakeLocalStore = {
      enable: false
    }
    const persistedStorageMiddleware = persistedStorageMiddlewareCreator(
      fakeSessionStore,
      fakeLocalStore
    )
    const dispatch = persistedStorageMiddleware()(stubNext)

    testNextAction(dispatch)
  })

  context('action type is unknown', () => {
    const persistedStorageMiddleware = persistedStorageMiddlewareCreator()
    const dispatch = persistedStorageMiddleware()(stubNext)

    const dummyAction = { type: 'dummy action' }

    testNextAction(dispatch, dummyAction)
  })
})
