describe 'Form', ->
  React = require 'react'
  Form = React.createFactory require('../../src/components/form')
  createClass = require 'create-react-class'
  
  {div} = require 'react-dom-factories'

  props = {}
  child = null
  closeSpy = sinon.spy()
  saveSpy = sinon.spy()
  onCloseSpy = sinon.spy()
  onSaveCompleteSpy = sinon.spy()

  beforeEach ->

    childClass = createClass
      render: -> div {className: 'child'}
      
    child = React.createFactory(childClass)

    closeSpy.reset()
    saveSpy.reset()
    onCloseSpy.reset()
    onSaveCompleteSpy.reset()

    props = 
      close: closeSpy
      save: saveSpy
      onClose: onCloseSpy
      onSaveComplete: onSaveCompleteSpy
      title: 'Form Title'
      showClose: yes

  it 'Should render a div with the default .form className', ->

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'div')[0]

    expect(el).to.exist
    expect(el.className.search('form')).to.be.above(-1)


  it 'Should NOT render bar if loading is true', ->
    props.loading = true

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'div')[0]

    expect(el).to.exist
    expect(el.className.search('bar')).to.equal(-1)


  it 'Should render a title bar with the .bar className', ->

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'div')[1]

    expect(el).to.exist
    expect(el.className.search('bar')).to.be.above(-1)


  it 'Should render a title with the .title className', ->

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'div')[2]

    expect(el).to.exist
    expect(el.className.search('title')).to.be.above(-1)

  
  it 'Should render a title with the passed title', ->

    props.title = 'Form Title'

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'div')[2]

    expect(el.innerText).to.equal(props.title)


  it 'Should render a close button by default', ->

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'button')[1]

    expect(el.innerText).to.equal('Cancel')


  it 'Should render the close button with props.closeBtnText if showClose is true', ->

    props.closeBtnText = 'Done'

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'button')[1]

    expect(el.innerText).to.equal('Done')


  it 'Should NOT render the close button with props.closeBtnText if showClose is false', ->

    props.closeBtnText = 'Done'
    props.showClose = no

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'button')

    expect(el.length).to.equal(1)


  it 'Should render the save button if canUpdate is true', ->

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'button')[0]

    expect(el.innerText).to.equal('Save')


  it 'Should NOT render the save button if canUpdate is true', ->

    props.canUpdate = no
    props.showClose = no

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'button')

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


  it 'Should call props.close when the close button is clicked', ->

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'button')[1]

    Simulate.click el

    expect(props.close.called).to.equal(yes)


  it 'Should NOT call props.close when the close button is clicked and there are unsaved changes', ->

    props.unSavedChanges = yes

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'button')[1]

    Simulate.click el

    expect(props.close.called).to.equal(no)


  it 'Should call props.onClose when the close button is clicked', ->

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithTag(form, 'button')[1]

    Simulate.click el

    expect(props.onClose.called).to.equal(yes)


  it 'Should render props.buttons as passed', ->

    props.buttons = [
      {
        name: 'Create'
        handler: sinon.spy()
      }
    ]

    form = renderIntoDocument Form props

    btns = scryRenderedDOMComponentsWithTag(form, 'button')

    expect(btns.length).to.equal(3)
    expect(btns[2].innerText).to.equal('Create')


  it 'Should call button.handler when button is click', ->

    props.buttons = [
      {
        name: 'Create'
        handler: sinon.spy()
      }
    ]

    form = renderIntoDocument Form props

    btn = scryRenderedDOMComponentsWithTag(form, 'button')[2]

    Simulate.click btn

    expect(props.buttons[0].handler.called).to.equal(yes)


  it 'Should disable a button when button.disabled is true', ->

    props.buttons = [
      {
        name: 'Create'
        handler: sinon.spy()
        disabled: yes
      }
    ]

    form = renderIntoDocument Form props

    btn = scryRenderedDOMComponentsWithTag(form, 'button')[1]

    Simulate.click btn

    expect(props.buttons[0].disabled).to.equal(yes)


  it 'Should render the passed children', ->

    form = renderIntoDocument Form(props, child())

    el = scryRenderedDOMComponentsWithClass(form, 'child')[0]

    expect(el).to.exist


  it 'Should show the confirm save overlay when there is a saveState', ->

    props.saveState = 'pending'

    form = renderIntoDocument Form props

    el = scryRenderedDOMComponentsWithClass(form, 'confirm-save-wrap')[0]

    expect(el).to.exist



  it 'Should show the spinner instead of the children if loading is true', ->

    props.loading = yes

    form = renderIntoDocument Form(props, child())

    el = scryRenderedDOMComponentsWithClass(form, 'child')[0]
    loader = scryRenderedDOMComponentsWithClass(form, 'spinner-wrapper')[0]

    expect(el).to.not.exist
    expect(loader).to.exist
  

  it 'Should call @props.onSaveComplete and NOT call @props.close when saveComplete is called and closeAfterSave is false', ->

    props.closeAfterSave = no

    form = renderIntoDocument Form(props, child())

    form.saveComplete()

    expect(closeSpy.called).to.equal(no)
    expect(onSaveCompleteSpy.called).to.equal(yes)