import ExtraTimeMultiplier from '..'
import ReactTestUtils from 'react-dom/test-utils'

describe('ExtraTimeMultiplier', () => {
  const sandbox = sinon.createSandbox()
  const onChangeStub = sandbox.stub()

  const defaultProps = {
    onChange: onChangeStub,
    timerMultiplierValue: 1,
    maxMultiplier: 99,
    minMultiplier: 1,
  }

  const testbed = createTestbed(ExtraTimeMultiplier, defaultProps)

  const getInputByLabelText = (testbed, labelText) => {
    const labels = testbed.findChildrenByTagName('label')
    const label = labels.filter(el => {
      return testbed.getText(el).indexOf(labelText) > -1
    })

    return label[0].querySelector ? label[0].querySelector('input') : null
  }

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

  it('renders one input', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    expect(input).to.exist()
  })

  it('should accept a decimal input', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    testbed.change(input, '2.85')
    ReactTestUtils.Simulate.blur(input)
    expect(input.value).to.equal('2.85')
  })

  it('should callback the correct multiplier', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    testbed.change(input, '3.81')
    ReactTestUtils.Simulate.blur(input)
    expect(onChangeStub).to.have.been.calledWith(3.81)
  })

  it('should callback a maximum of maxMultiplier', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    testbed.change(input, defaultProps.maxMultiplier * 2)
    ReactTestUtils.Simulate.blur(input)
    expect(onChangeStub).to.have.been.calledWith(defaultProps.maxMultiplier)
  })

  it('should callback a minimum of minMultiplier', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    testbed.change(input, defaultProps.minMultiplier * -2)
    ReactTestUtils.Simulate.blur(input)
    expect(onChangeStub).to.have.been.calledWith(defaultProps.minMultiplier)
  })

  it('should pass error message to child on invalid input', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    testbed.change(input, 'apple')
    expect(testbed.getText()).to.include('apple is not a valid number')
  })

  it('should pass error message to child on invalid input followed by blur', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    testbed.change(input, 'banana')
    ReactTestUtils.Simulate.blur(input)
    expect(testbed.getText()).to.include('banana is not a valid number')
  })

  it('should not pass error message to child on valid input', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    testbed.change(input, 'pear')
    testbed.change(input, '1.51')
    expect(testbed.getText()).not.to.include('is not a valid number')
  })

  it('should reset to valid input after blur', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    testbed.change(input, '1.51')
    testbed.change(input, 'pear')
    ReactTestUtils.Simulate.blur(input)
    expect(input.value).to.equal('1.51')
  })

  it('should reset to max on increment above max', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    testbed.change(input, '9999999')
    ReactTestUtils.Simulate.keyDown(input, { key: 'ArrowUp', keyCode: 38 })
    expect(Number(input.value)).to.equal(defaultProps.maxMultiplier)
    expect(onChangeStub).to.have.been.calledWith(defaultProps.maxMultiplier)
  })

  it('should reset to min on decrement  below min', () => {
    testbed.render()
    const input = getInputByLabelText(testbed, 'Multiplier')
    testbed.change(input, '-25')
    ReactTestUtils.Simulate.keyDown(input, { key: 'ArrowDown', keyCode: 40 })
    expect(Number(input.value)).to.equal(defaultProps.minMultiplier)
    expect(onChangeStub).to.have.been.calledWith(defaultProps.minMultiplier)
  })

  it('should be accessible', (done) => {
    testbed.render()
    testbed.checkA11yStandards(done)
  })
})
