import { fromJS } from 'immutable'

import SessionItemResult from '../presenter'

import PositionBox from '../../../positionBox/PositionBox'
import SessionItem from '../../../../../records/SessionItem'
import SessionItemResultRecord from '../../../../../records/SessionItemResult'
import Item from '../../../../../records/Item'

import styles from '../styles.css'

describe('SessionItemResult', () => {
  const stubbedItem = new Item({itemBody: '<div>foo</div>'})
  stubbedItem.getInteractionType = () => ({slug: 'foo'})
  const props = {
    sessionItem: new SessionItem({item: stubbedItem, position: 1}),
    sessionItemResult: new SessionItemResultRecord()
  }
  const testbed = createTestbed(SessionItemResult, props)

  shouldRenderComponent(testbed, {}, SessionItemResult)

  describe('#result', () => {
    context('with SessionItemResult', () => {
      it('returns a sessionItemResult with given properties', () => {
        testbed.render({sessionItemResult: new SessionItemResultRecord({score: 1})})
        expect(testbed.subject.points).to.eq(1)
      })
    })
  })

  describe('a11y tests', () => {
    it('should meet a11y standards', (done) => {
      testbed.render()
      testbed.checkA11yStandards(done)
    })

    it('reads regrade alert when question number gets screenreader focus', () => {
      testbed.render({
        sessionItemResult: new SessionItemResultRecord({
          regradeInfo: fromJS({regraded: true})
        })
      })
      const positionBox = testbed.findChildByType(PositionBox)
      expect(positionBox.props.headingText).to.include('question has been regraded')
    })
  })

  describe('points display', () => {
    it('should display score and points possible when both are present', () => {
      testbed.render({
        sessionItemResult: new SessionItemResultRecord({score: 10}),
        sessionItem: new SessionItem({
          pointsPossible: 20
        })
      })

      const pointsDisplay = testbed.findChildrenByClass(styles.points)[0]
      expect(testbed.getText(pointsDisplay)).to.include('10 / 20 points')
    })

    it('should only display score when score is present and points possible is not present', () => {
      testbed.render({
        sessionItemResult: new SessionItemResultRecord({score: 10}),
        sessionItem: new SessionItem()
      })

      const pointsDisplay = testbed.findChildrenByClass(styles.points)[0]
      expect(testbed.getText(pointsDisplay)).to.include('10 points earned')
    })

    it('should only display points possible when points possible is present and score is not present', () => {
      testbed.render({
        sessionItemResult: new SessionItemResultRecord(),
        sessionItem: new SessionItem({
          pointsPossible: 20
        })
      })

      const pointsDisplay = testbed.findChildrenByClass(styles.points)[0]
      expect(testbed.getText(pointsDisplay)).to.include('20 points possible')
    })

    it('should not display anything when score and points possible are both missing', () => {
      testbed.render({
        sessionItemResult: new SessionItemResultRecord(),
        sessionItem: new SessionItem()
      })

      const pointsDisplay = testbed.findChildrenByClass(styles.points)[0]
      expect(testbed.getText(pointsDisplay)).to.not.include('points')
    })
  })

  describe('feedback tests', () => {
    const feedbackTestbed = createTestbed(withContext(SessionItemResult), props)

    it('should render feedback if it exists', () => {
      const sessionItemResult = new SessionItemResultRecord({
        itemId: 1,
        feedback: {
          itemFeedback: {
            correct: 'correct',
            neutral: 'general'
          }
        }
      })
      feedbackTestbed.render({sessionItemResult: sessionItemResult})
      expect(feedbackTestbed.getText()).to.have.string('General Feedback')
      expect(feedbackTestbed.getText()).to.have.string('Correct Feedback')
      expect(feedbackTestbed.getText()).to.not.have.string('Incorrect Feedback')
    })

    it('should not render feedback section if no feedback', () => {
      feedbackTestbed.render()
      expect(feedbackTestbed.getText()).to.not.have.string('Correct Feedback')
      expect(feedbackTestbed.getText()).to.not.have.string('Incorrect Feedback')
      expect(feedbackTestbed.getText()).to.not.have.string('General Feedback')
    })

    it('should render grader feedback if it exists', () => {
      const sessionItemResult = new SessionItemResultRecord({
        itemId: 1,
        feedback: {
          graderFeedback: { content: 'content'}
        }
      })
      feedbackTestbed.render({sessionItemResult: sessionItemResult})
      expect(feedbackTestbed.getText()).to.have.string('Grader Feedback')
    })

    it('should not render grader feedback if no feedback', () => {
      feedbackTestbed.render()
      expect(feedbackTestbed.getText()).to.not.have.string('Grader Feedback')
    })

    it('should not render grader feedback with hideGraderFeedback', () => {
      const sessionItemResult = new SessionItemResultRecord({
        feedback: {
          graderFeedback: { content: 'content'}
        }
      })
      feedbackTestbed.render({
        sessionItemResult: sessionItemResult,
        hideGraderFeedback: true
      })
      expect(feedbackTestbed.getText()).to.not.have.string('Grader Feedback')
    })
  })
})
