import { expect } from 'chai'

import { getQuizSession, getQuizSessions, reopenQuizSession } from '../quizSessions'
import Fetcher from '../../../common/util/Fetcher'
import makeFakeFetch from '../../../../tests/util/fakeFetch'

import { jsoniblePromise } from '../../../common/util/jsonify'

import {
  handleQuizSessionResponse,
  handleQuizSessionsResponse
} from '../../../common/api/callHandlers'

describe('quizSession api actions', () => {
  const quizId = '456'
  const sessionId = '123'
  const resultId = '789'

  const quizSessionData = {id: sessionId}
  const quizSessionResult = {id: resultId}

  const fetchStub = sinon.stub()
  const dispatchStub = sinon.stub()
  const dispatchStubIgnore = sinon.stub()
  const getStateStub = sinon.stub()

  useFakeFetching({dispatchStub, getStateStub, fetchStub})

  describe('getQuizSessions', () => {
    const stubbedGetQuizSessionsCall = () => {
      const response = jsoniblePromise([quizSessionData])
      Fetcher.fakeFetch = makeFakeFetch(response)
      return getQuizSessions(quizId)(dispatchStub, getStateStub)
    }

    it('should hit the right endpoint', () => {
      Fetcher.fakeFetch = fetchStub
      getQuizSessions(quizId)(dispatchStubIgnore, getStateStub)
      expect(
        fetchStub.calledWith(`/api/quizzes/${quizId}/quiz_sessions`)
      ).to.be.true()
    })

    it('should trigger additional actions', async () => {
      await stubbedGetQuizSessionsCall()

      const expectedResponse = handleQuizSessionsResponse([quizSessionData])
      checkActionDispatched(dispatchStub, expectedResponse[0])
    })
  })

  describe('getQuizSession', () => {
    const stubbedGetQuizSessionCall = () => {
      const response = jsoniblePromise(quizSessionResult)
      Fetcher.fakeFetch = makeFakeFetch(response)
      return getQuizSession(sessionId)(dispatchStub, getStateStub)
    }

    it('should hit the right endpoint', () => {
      Fetcher.fakeFetch = fetchStub
      getQuizSession(sessionId)(dispatchStubIgnore, getStateStub)
      expect(
        fetchStub.calledWith(`/api/quiz_sessions/${sessionId}`)
      ).to.be.true()
    })

    it('should trigger additional actions', async () => {
      await stubbedGetQuizSessionCall()

      const expectedResponse = handleQuizSessionResponse(quizSessionResult)
      checkActionDispatched(dispatchStub, expectedResponse[0])
    })
  })

  describe('reopenQuizSession', () => {
    const stubbedGetQuizSessionCall = () => {
      const response = jsoniblePromise(quizSessionResult)
      Fetcher.fakeFetch = makeFakeFetch(response)
      return reopenQuizSession(sessionId)(dispatchStub, getStateStub)
    }

    it('should hit the right endpoint', () => {
      Fetcher.fakeFetch = fetchStub
      reopenQuizSession(sessionId)(dispatchStubIgnore, getStateStub)
      expect(
        fetchStub.calledWith(`/api/quiz_sessions/${sessionId}/reopen`)
      ).to.be.true()
    })

    it('should trigger additional actions', async () => {
      await stubbedGetQuizSessionCall()

      const expectedResponse = handleQuizSessionResponse(quizSessionResult)
      checkActionDispatched(dispatchStub, expectedResponse[0])
    })
  })
})
