import { expect } from 'chai'
import serializeEvent from '../serializeEvent'
import {
  RESPONSE,
  SESSION_STARTED_OR_RESUMED_EVENT
} from '@instructure/quiz-common/lib/constants'

import fakeStore from '../../../../tests/util/minimalStore'
import {setFakeStore, unsetFakeStore} from '../../../reduxStore'
import {
  editResponse,
  sessionStartOrResumeEvent
} from '../../actions/taking'

describe('serializeEvent', () => {
  // testrail test_id: C2954596, C2954597
  const activeQuizSessionId = '3'
  const fakeState = ({
    taking: {
      browserSessionId: 'session_id_guid'
    },
    quizSessions: {
      activeQuizSessionId,
      [activeQuizSessionId]: {
        accountUuid: 'accountUuid',
        eventCreationToken: 'jwt_token',
        id: activeQuizSessionId
      }
    }
  })

  before(() => {
    setFakeStore(fakeStore(fakeState).getState())
  })

  after(() => {
    unsetFakeStore()
  })

  context(RESPONSE, () => {
    context('edit response', () => {
      it('returns a well formed object', () => {
        const sessionItem = {position: 1, getItem: () => ({id: '1'})}
        const action = editResponse(sessionItem, 'bar')

        const eventData = Object.assign(
          {},
          action.payload,
          { browserSessionId: 'session_id_guid', clientTimestamp: 'timestamp' }
        )
        const serializedEvent = serializeEvent(action)

        const expectedEvent = {
          accountUuid: 'accountUuid',
          eventCreationToken: 'jwt_token',
          eventData,
          eventType: RESPONSE,
          quizSessionId: '3'
        }

        expect(serializedEvent).to.have.all.keys(Object.keys(expectedEvent))
        expect(serializedEvent).to.have.property('accountUuid').that.equals(expectedEvent.accountUuid)
        expect(serializedEvent).to.have.property('eventCreationToken').that.is.an('string')
        expect(serializedEvent).to.have.property('eventType').that.equals(expectedEvent.eventType)
        expect(serializedEvent).to.have.property('quizSessionId').that.equals(expectedEvent.quizSessionId)

        expect(serializedEvent).to.have.property('eventData').that.is.an('object')
        expect(serializedEvent.eventData).to.have.property('browserSessionId').that.equals(eventData.browserSessionId)
        expect(serializedEvent.eventData).to.have.property('clientTimestamp').that.is.a('date')
        expect(serializedEvent.eventData).to.have.property('userResponse').that.equals(eventData.userResponse)
        expect(serializedEvent.eventData).to.have.property('itemId').that.equals(eventData.itemId)
        expect(serializedEvent.eventData).to.have.property('position').that.equals(eventData.position)
      })
    })
  })

  context(SESSION_STARTED_OR_RESUMED_EVENT, () => {
    context('start a new taking session (or resume)', () => {
      it('returns a well formed object', () => {
        const userAgent = 'userAgent'
        const action = sessionStartOrResumeEvent(userAgent)

        const serializedEvent = serializeEvent(action)

        const expectedEvent = {
          accountUuid: 'accountUuid',
          eventCreationToken: 'jwt_token',
          eventData: {
            browserSessionId: 'session_id_guid',
            userAgent
          },
          eventType: SESSION_STARTED_OR_RESUMED_EVENT,
          quizSessionId: '3'
        }

        expect(serializedEvent).to.have.all.keys(Object.keys(expectedEvent))
        expect(serializedEvent).to.have.property('accountUuid').that.equals(expectedEvent.accountUuid)
        expect(serializedEvent).to.have.property('eventCreationToken').that.is.an('string')
        expect(serializedEvent).to.have.property('eventType').that.equals(expectedEvent.eventType)
        expect(serializedEvent).to.have.property('quizSessionId').that.equals(expectedEvent.quizSessionId)

        expect(serializedEvent).to.have.property('eventData').that.is.an('object')
          .with.property('userAgent').that.equals(userAgent)
        expect(serializedEvent.eventData).to.have.property('browserSessionId').that.equals('session_id_guid')
        expect(serializedEvent.eventData).to.have.property('clientTimestamp').that.is.a('date')
      })
    })
  })
})
