import { fromJS } from 'immutable'
import Avatar from '@instructure/ui-elements/lib/components/Avatar'

import { QUIZ_SESSIONS_FETCH_CALL } from '@instructure/quiz-common/lib/constants'

import ConnectedModerateTable, { ModerateTable, mapStateToProps, mapDispatchToProps } from '../index'
import reduxStore, { setFakeStore, unsetFakeStore } from '../../../../../reduxStore'

describe('ModerateTable', () => {
  const sandbox = sinon.createSandbox()
  const props = {
    onModerateLogClick () {},
    getQuizSessions () {},
    tableData: [
      { avatar: 'zomgModerateTable', id: '42', name: 'lolwut', quizSessionIds: ['1'] },
      { avatar: 'lulzModerateTable', id: '77', name: 'wutlol', quizSessionIds: ['2'] }
    ],
    quizId: '1'
  }

  afterEach(() => {
    sandbox.resetHistory()
  })

  stubComponent(Avatar)

  const testbedWithContext = createTestbed(withContext(ConnectedModerateTable, {}), props)

  useFakeFetching({
    dispatchStub: sandbox.stub(),
    getStateStub: sandbox.stub(),
    fetchStub: sandbox.stub()
  })

  shouldRenderComponent(testbedWithContext, {}, ConnectedModerateTable)

  context('mapStateToProps', () => {
    afterEach(() => {
      unsetFakeStore()
    })

    it('computes isFetching', () => {
      let result

      setFakeStore(fromJS({
        calls: { [QUIZ_SESSIONS_FETCH_CALL]: { requestStatus: 'calling' } }
      }))

      result = mapStateToProps(reduxStore.getAppState(), props)
      expect(result).to.deep.eq({ isFetching: true })

      setFakeStore(fromJS({
        calls: { [QUIZ_SESSIONS_FETCH_CALL]: { requestStatus: 'success' } }
      }))

      result = mapStateToProps(reduxStore.getAppState(), props)
      expect(result).to.deep.eq({ isFetching: false })
    })
  })

  context('mapDispatchToProps', () => {
    it('receives getQuizSessions', () => {
      const { getQuizSessions } = mapDispatchToProps
      expect(getQuizSessions).to.be.a('function')
    })
  })

  context('#getQuizSessions', () => {
    // NOTE: test w/o connect component wrapper
    const testbedWithContext = createTestbed(withContext(ModerateTable, {}), props)

    beforeEach(() => {
      sandbox.spy(props, 'getQuizSessions')
    })

    afterEach(() => {
      sandbox.restore()
    })

    it('is invoked on mount', () => {
      testbedWithContext.render()
      expect(props.getQuizSessions).to.have.been.calledOnce()
    })

    it('is invoked on update from new props', () => {
      testbedWithContext.render()
      testbedWithContext.render({
        tableData: [
          { avatar: 'lolol', id: '99', name: 'wutwut', quizSessionIds: ['3'] }
        ]
      })
      expect(props.getQuizSessions).to.have.been.calledTwice()
    })

    it('does not fetch on update if the sessions are the same', () => {
      testbedWithContext.render()
      testbedWithContext.render({ tableData: props.tableData })
      expect(props.getQuizSessions).to.have.been.calledOnce()
    })

    it('does not fetch when there are no quizSessionIds', () => {
      testbedWithContext.render({
        tableData: [
          { avatar: 'nope', id: '101', name: 'empty', quizSessionIds: [] }
        ]
      })

      expect(props.getQuizSessions).to.not.have.been.called()
    })
  })
})
