import { shallowMount } from '@vue/test-utils';
import dropdownQuestion from '@/digital-components/dropdown-question/dropdown-question.vue';

// Mock CMS content
const questionText = 'Question Text';
const mockMixin = {
    methods: {
        getCmsContent: jest.fn().mockImplementation(() => questionText)
    }
};

// TODO: Remove the following from dropdown-question.vue -> :class="(errors && errors.length) || hasError ? 'has-error' : ''"
// It is not being used.
describe('dropdownQuestion.vue', () => {
    it('Should render a select input', async () => {
        // Arrange
        const wrapper = shallowMount(dropdownQuestion, {
            propsData: {
                options: {}
            },
            mixins: [mockMixin]
        });

        wrapper.getCmsContent = jest.fn();

        // Act
        const select = wrapper.find('select');

        // Assert
        expect(select.exists()).toBe(true);
    });

    it("Should render the 'questionText' data value as the label text.", async () => {
    // Arrange
        const wrapper = shallowMount(dropdownQuestion, {
            propsData: {
                options: {}
            },
            mixins: [mockMixin]
        });

        // Act
        const label = wrapper.find('label');

        // Assert
        expect(label.text()).toContain(questionText);
    });

    it('Should return input id as the id of the select field', async () => {
    // Arrange
        const wrapper = shallowMount(dropdownQuestion, {
            propsData: {
                inputId: 'input ID',
                options: {}
            },
            mixins: [mockMixin]
        });

        // Act
        const select = wrapper.find('select');

        // Assert
        expect(select.attributes().id).toEqual('input ID');
    });

    it("Should render the 'questionText' data value as the aria-label attribute.", async () => {
    // Arrange
        const wrapper = shallowMount(dropdownQuestion, {
            propsData: {
                options: {}
            },
            mixins: [mockMixin]
        });

        // Act
        const label = wrapper.find('label');

        // Assert
        expect(label.attributes('aria-label')).toContain(questionText);
    });

    it('Should return aria-disabled state as disabled', async () => {
    // Arrange
        const wrapper = shallowMount(dropdownQuestion, {
            propsData: {
                options: {},
                isDisabled: true
            },
            mixins: [mockMixin]
        });

        // Act
        const select = wrapper.find('select');

        // Assert
        expect(select.attributes('aria-disabled')).toEqual('true');
    });

    it('Should emit new value when modelValue is changed', async () => {
    // Arrange
        const wrapper = shallowMount(dropdownQuestion, {
            propsData: {
                options: {},
                modelValue: 'val'
            },
            mixins: [mockMixin]
        });

        // Act
        await wrapper.find('select').setValue('val2');

        // Assert
        expect(wrapper.emitted()).toHaveProperty('change');
    });

    it('Should call this.handleChange with new value when selectedOption is changed', async () => {
    // Arrange
        const wrapper = shallowMount(dropdownQuestion, {
            propsData: {
                options: {},
                modelValue: '0'
            },
            mixins: [mockMixin]
        });

        wrapper.vm.handleChange = jest.fn().mockImplementation(() => {});

        // Act
        wrapper.vm.$options.watch.selectedOption.call(wrapper.vm, 1);

        // Assert
        expect(wrapper.vm.handleChange).toHaveBeenCalled();
    });
});
