import { newE2EPage } from '@stencil/core/testing'

describe('gd-tag-input', () => {
    let page, component
   
    const testTags = ['tag1', 'tag2', 'tag3', 'tag4']

    beforeEach(async () => {
        page = await newE2EPage()

        await page.setContent(`
            <gd-tag-input value="${testTags.join(',')}"></gd-tag-input>
        `)

        component = await page.find('gd-tag-input')
    })

    it('renders', async () => {
        expect(component).toHaveClass('hydrated')
    })

    it('should render the internal tags component', async () => {
        let tags = await page.find('gd-tag-input >>> tags')

        expect(tags).not.toBeNull()
    })

    it('should render a tag for each tag in value prop', async () => {
        let tags = await page.findAll('gd-tag-input >>> tag')
        
        expect(tags).toHaveLength(testTags.length)
    })

    it('changing the value should update the visible tags', async () => {
        component.setProperty('value', 'foo')

        await page.waitForChanges()

        let tags = await page.findAll('gd-tag-input >>> tag')
        
        expect(tags).toHaveLength(1)
    })

    it('should add a new tag using the addTags method', async () => {
        await component.callMethod('addTags', 'foo')
        await page.waitForChanges()

        let tags = await page.findAll('gd-tag-input >>> tag')
        
        expect(tags).toHaveLength(testTags.length + 1)
    })

    it('adding a new tag should trigger the tagsChange event with the new set of tags', async () => {
        const eventSpy = await component.spyOnEvent('tagsChange')
        const newTag = 'bacon'
        const newTags = [].concat(testTags, newTag).join(', ')

        await component.callMethod('addTags', newTag)
        await page.waitForChanges()

        expect(eventSpy).toHaveReceivedEvent()
        expect(eventSpy).toHaveReceivedEventDetail(newTags)
    })

    it('should be able to add more than one new tag at a time', async () => {
        const eventSpy = await component.spyOnEvent('tagsChange')
        const newTag = ['foo', 'bar']
        const newTags = [].concat(testTags, newTag).join(', ')

        await component.callMethod('addTags', newTag)
        await page.waitForChanges()

        let tags = await page.findAll('gd-tag-input >>> tag')
        
        expect(tags).toHaveLength(testTags.length + newTag.length)
        expect(eventSpy).toHaveReceivedEvent()
        expect(eventSpy).toHaveReceivedEventDetail(newTags)
    })

    it('should filter out bad words from tags', async () => {
        const eventSpy = await component.spyOnEvent('tagsChange')
        const badWords = ['ass', 'you ahole']
        const cleanTags = '***, you *****'

        component.setProperty('value', badWords.join(', '))
        await page.waitForChanges()

        expect(eventSpy).toHaveReceivedEventDetail(cleanTags)
    })
})
