import TagSelect from '../index'

import Tag from '@instructure/ui-elements/lib/components/Tag'

describe('TagSelect', () => {
  const onChangeStub = sinon.stub()
  const onInputChangeStub = sinon.stub()

  const ConnectedTagSelect = withContext(TagSelect)
  const testbed = createTestbed(ConnectedTagSelect, {
    noMatchText: '404 TAG NOT FOUND',
    onChange: onChangeStub,
    onInputChange: onInputChangeStub
  })
  shouldRenderComponent(testbed, {}, TagSelect)

  afterEach(() => {
    onChangeStub.resetHistory()
    onInputChangeStub.resetHistory()
  })

  it('should render select label', () => {
    testbed.render()
    const text = testbed.getText()
    expect(text).to.include('Tags and Metadata')
  })

  it('should render one selected option', () => {
    testbed.render({
      tags: [
        {id: '1', value: 'waldo'}
      ]
    })
    const text = testbed.getText()
    expect(text).to.include('waldo')
  })

  it('should call onChange when a tag is removed', () => {
    testbed.render({
      tags: [
        {id: '1', value: 'waldo'}
      ]
    })
    testbed.click(testbed.findChildByType(Tag))
    expect(onChangeStub).to.be.called()
  })

  it('display empty option when entering text', () => {
    testbed.render()
    testbed.click(testbed.findChildByTagName('input'))
    const text = testbed.getText()
    expect(text).to.include('404 TAG NOT FOUND')
  })

  it('offers tag creation when text is entered', async () => {
    testbed.render({
      allowNewTags: true
    })
    const input = testbed.findChildByTagName('input')
    testbed.click(input)
    testbed.change(input, 'hi')
    const createOption = testbed.findChildrenBySelector('[role=option]')[0]
    const text = createOption.innerHTML
    expect(text).to.include('Create new tag: hi')
    testbed.click(createOption)
    expect(onChangeStub).to.be.calledWith([{ value: 'hi' }])
  })

  it('does not offer to create a tag that is already selected', async () => {
    testbed.render({
      tags: [
        { value: 'waldo' }
      ],
      allowNewTags: true
    })
    const input = testbed.findChildrenBySelector('input[role=combobox]')[0]
    testbed.click(input)
    testbed.change(input, 'waldo')
    const emptyOption = testbed.findChildrenBySelector('[role=option]')[0]
    const text = emptyOption.innerHTML
    expect(text).to.include('Tag already selected: waldo')
    testbed.click(emptyOption)
    expect(onChangeStub).to.not.be.called()
  })

  it('offers all tag suggestions', () => {
    testbed.render({
      tagSuggestions: [{ id: '1', value: 'tag-1' }, { id: '2', value: 'tag-2' }]
    })
    testbed.click(testbed.findChildByTagName('input'))
    const text = testbed.getText()
    expect(text).to.include('tag-1')
    expect(text).to.include('tag-2')
  })

  it('does not offer tag creation on suggested tags', () => {
    testbed.render({
      allowNewTags: true,
      tagSuggestions: [{ id: '1', value: 'tag-1' }]
    })
    testbed.click(testbed.findChildByTagName('input'))
    const text = testbed.getText()
    expect(text).to.not.include('Create new tag')
  })

  it('does not remove existing tag with text matching the tag id', () => {
    testbed.render({
      tags: [
        { value: 'waldo' }
      ],
      tagSuggestions: [{ id: '1', value: 'tag-1' }]
    })
    const text = testbed.getText()
    expect(text).to.include('waldo')
  })

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