describe 'MultiSelect', ->
  React = require 'react'
  MultiSelect = React.createFactory require('../../src/components/multi_select')
  TestUtils = require 'react-addons-test-utils'
  ReactDOM = require 'react-dom'
  _ = require 'lodash'

  options = []
  flatOptions = []

  beforeEach ->
    flatOptions = ['one', 'two', 'three', 'four']
    options = [
      {
        name: 'one'
        someValue: 1
      }
      {
        name: 'two'
        someValue: 2
      }
      {
        name: 'three'
        someValue: 3
      }
      {
        name: 'four'
        someValue: 4
      }
    ]

  #--------------------------------------------------------------------- Default Props
  # it 'Should have default props for allowDefault, filter, editPlaceholder, searchPlaceholder, tabIndex', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: []
      }
    defaultProps = multiSelect.props
    expect(defaultProps.allowDefault).to.equal(false)
    expect(defaultProps.filter).to.equal('auto')
    expect(defaultProps.editPlaceholder).to.equal('Edit Items')
    expect(defaultProps.searchPlaceholder).to.equal('Filter Items')
    expect(defaultProps.tabIndex).to.equal(-1)


  #--------------------------------------------------------------------- getInitialState
  it 'Should set combine options and values into selected and notSelected state when passed and array of options objects', ->

    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
      }

    {selected, notSelected} = multiSelect.state

    selectedTest = _.isEqual selected, [
      {
        isSelected: true
        label: 'two'
        value: 2
        isVisible: true
      }
      {
        isSelected: true
        label: 'four'
        value: 4
        isVisible: true
      }
    ]

    notSelectedTest = _.isEqual notSelected, [
      {
        isSelected: false
        label: 'one'
        value: 1
        isVisible: true
      }
      {
        isSelected: false
        label: 'three'
        value: 3
        isVisible: true
      }
    ]

    expect(selectedTest).to.equal(true)
    expect(notSelectedTest).to.equal(true)


  it 'Should set combine options and values into selected and notSelected state when passed flat array of options', ->

    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: flatOptions
        values: ['two', 'four']
      }

    {selected, notSelected} = multiSelect.state

    selectedTest = _.isEqual selected, [
      {
        isSelected: true
        label: 'two'
        value: 'two'
        isVisible: true
      }
      {
        isSelected: true
        label: 'four'
        value: 'four'
        isVisible: true
      }
    ]

    notSelectedTest = _.isEqual notSelected, [
      {
        isSelected: false
        label: 'one'
        value: 'one'
        isVisible: true
      }
      {
        isSelected: false
        label: 'three'
        value: 'three'
        isVisible: true
      }
    ]

    expect(selectedTest).to.equal(true)
    expect(notSelectedTest).to.equal(true)

  #--------------------------------------------------------------------- Adding and removing
  it 'Should remove a selected option when clicked', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
        valueOfDefault: 2
        onRemove: ->
      }

    multiSelect.setState
      isActive: true

    options = TestUtils.scryRenderedDOMComponentsWithClass multiSelect, 'multiselect-option'

    TestUtils.Simulate.click options[0]

    {notSelected} = multiSelect.state

    expect(notSelected.length).to.equal(3)

  it 'Should add a not selected option when clicked', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
      }

    multiSelect.setState
      isActive: true

    options = TestUtils.scryRenderedDOMComponentsWithClass multiSelect, 'multiselect-option'

    TestUtils.Simulate.click options[3]

    {selected} = multiSelect.state

    expect(selected.length).to.equal(3)


  #--------------------------------------------------------------------- isActive State
  it 'Should become active when clicked', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
        valueOfDefault: 2
      }

    container = TestUtils.findRenderedDOMComponentWithClass multiSelect, 'multiselect'

    TestUtils.Simulate.click container

    expect(multiSelect.state.isActive).to.equal(true)


  #--------------------------------------------------------------------- Filtering
  it 'Should show the filter field when the filter prop is true', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
        valueOfDefault: 2
        filter: true
      }

    multiSelect.setState
      isActive: true

    expect(multiSelect.filterShouldBeShown()).to.equal(true)

    multiSelect.refs.filterField.blur()

  it 'Should show the filter field when the filter prop is auto and the options are more then 4', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: ['one', 'two', 'three', 'four', 'five']
        values: []
        filter: 'auto'
      }

    multiSelect.setState
      isActive: true

    expect(multiSelect.filterShouldBeShown()).to.equal(true)

    multiSelect.refs.filterField.blur()


  it 'Should filter the not selected options by label when the user types in the filter field', (done) ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
        valueOfDefault: 2
        filter: true
      }

    multiSelect.setState
      isActive: true

    multiSelect.refs.filterField.blur()

    searchField = TestUtils.findRenderedDOMComponentWithClass multiSelect, 'search-input'

    TestUtils.Simulate.change searchField, {
      target:
        value: 'one'
    }

    {notSelected} = multiSelect.state

    setTimeout ->
      visibleTest = _.isEqual notSelected, [
        {
          isSelected: false
          label: 'one'
          value: 1
          isVisible: true
        }
        {
          isSelected: false
          label: 'three'
          value: 3
          isVisible: false
        }
      ]

      expect(visibleTest).to.equal(true)
      done()
    , 10

  #--------------------------------------------------------------------- Default
  it 'Should set the default to object with the value of the valueOfDefault prop', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
        valueOfDefault: 2
        allowDefault: true
      }

    {theDefault, selected} = multiSelect.state

    expect(theDefault).to.equal(selected[0])


  it 'Should show/hide the default buttons based on the allowDefault prop', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
        valueOfDefault: 2
        allowDefault: true
      }

    defaultButtons = TestUtils.scryRenderedDOMComponentsWithClass multiSelect, 'multiselect-default'

    expect(defaultButtons.length).to.be.above(0)

    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
        valueOfDefault: 2
        allowDefault: false
      }

    defaultButtons = TestUtils.scryRenderedDOMComponentsWithClass multiSelect, 'multiselect-default'

    expect(defaultButtons.length).to.equal(0)


  it 'Should set the default when the default button is clicked', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
        valueOfDefault: 2
        allowDefault: true
      }

    defaultButtons = TestUtils.scryRenderedDOMComponentsWithClass multiSelect, 'multiselect-default'

    TestUtils.Simulate.click defaultButtons[1]

    {theDefault, selected} = multiSelect.state

    expect(theDefault).to.equal(selected[1])



  #--------------------------------------------------------------------- Edit button, Tab Index & Focus
  it 'Should activate when the edit button is focused (when the tabIndex prop is set)', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
        valueOfDefault: 2
        tabIndex: 1
      }

    editButton = TestUtils.findRenderedDOMComponentWithClass multiSelect, 'multiselect-edit'

    tabValue = ReactDOM.findDOMNode(editButton).getAttribute('tabindex')

    expect(tabValue).to.equal('1')

    TestUtils.Simulate.focus editButton

    expect(multiSelect.state.isActive).to.equal(true)

  it 'Should set the edit button text based on the editPlaceholder prop', ->
    multiSelect = TestUtils.renderIntoDocument MultiSelect {
        options: options
        values: [2,4]
        labelField: 'name'
        valueField: 'someValue'
        valueOfDefault: 2
        editPlaceholder: 'Edit Numbers'
      }

    editButton = TestUtils.findRenderedDOMComponentWithClass multiSelect, 'multiselect-edit'

    text = ReactDOM.findDOMNode(editButton).textContent

    expect(text).to.equal('+ Edit Numbers')


    



  
  













  
