import { faker } from "@faker-js/faker";
import { BsDropdownOption } from "../bs-dropdown-option";
import { newSpecPage } from "@stencil/core/testing";
import { fireEvent } from "@testing-library/dom";
describe('bs-dropdown-option', () => {
  describe('Test rendering', () => {
    let value;
    beforeEach(() => {
      value = faker.random.word();
    });
    // data selected / aria-selected
    it('renders when selected false', async () => {
      const page = await newSpecPage({
        components: [BsDropdownOption],
        html: `<bs-dropdown-option value="${value}"></bs-dropdown-option>`
      });
      const liComp = page.root.shadowRoot.querySelector('li');
      expect(page.root.getAttribute('data-selected')).toBeNull();
      expect(liComp.getAttribute('data-selected')).toBeNull();
      expect(liComp.getAttribute('aria-selected')).toBeNull();
    });
    it('renders when selected true', async () => {
      const page = await newSpecPage({
        components: [BsDropdownOption],
        html: `<bs-dropdown-option value="${value}" selected></bs-dropdown-option>`
      });
      const liComp = page.root.shadowRoot.querySelector('li');
      expect(page.root.getAttribute('data-selected')).toBe('');
      expect(liComp.getAttribute('data-selected')).toBe('');
      expect(liComp.getAttribute('aria-selected')).toBe('true');
    });
    // data variant
    it('renders when variant not given', async () => {
      const page = await newSpecPage({
        components: [BsDropdownOption],
        html: `<bs-dropdown-option value="${value}"></bs-dropdown-option>`
      });
      const liComp = page.root.shadowRoot.querySelector('li');
      expect(page.root.getAttribute('data-variant')).toBeNull();
      expect(liComp.getAttribute('data-variant')).toBeNull();
    });
    it('renders when variant given', async () => {
      const variant = faker.random.word();
      const page = await newSpecPage({
        components: [BsDropdownOption],
        html: `<bs-dropdown-option value="${value}" variant="${variant}"></bs-dropdown-option>`
      });
      const liComp = page.root.shadowRoot.querySelector('li');
      expect(page.root.getAttribute('data-variant')).toBe(variant);
      expect(liComp.getAttribute('data-variant')).toBe(variant);
    });
    // shown
    it('renders when shown false', async () => {
      const page = await newSpecPage({
        components: [BsDropdownOption],
        html: `<bs-dropdown-option value="${value}"></bs-dropdown-option>`
      });
      const liComp = page.root.shadowRoot.querySelector('li');
      expect(liComp.getAttribute('tabIndex')).toBeNull();
    });
    it('renders when shown true', async () => {
      const page = await newSpecPage({
        components: [BsDropdownOption],
        html: `<bs-dropdown-option value="${value}" shown></bs-dropdown-option>`
      });
      const liComp = page.root.shadowRoot.querySelector('li');
      expect(liComp.getAttribute('tabIndex')).toBe('-1');
    });
  });
  describe('Test event handling', () => {
    describe('mouseenter', () => {
      it('handles mouseenter and emits mousefocus', async () => {
        const index = Number(faker.random.numeric(1));
        const page = await newSpecPage({
          components: [BsDropdownOption],
          html: `<bs-dropdown-option index="${index}"></bs-dropdown-option>`
        });
        const evSpy = jest.spyOn(page.rootInstance.mousefocus, 'emit');
        fireEvent.mouseEnter(page.root);
        expect(evSpy).toBeCalledWith(index);
      });
    });
    // optionselect
    describe('click', () => {
      it('handles click and emits optionselect', async () => {
        const id = faker.random.alphaNumeric(10);
        const index = Number(faker.random.numeric(1));
        const value = faker.random.word();
        const page = await newSpecPage({
          components: [BsDropdownOption],
          html: `
            <bs-dropdown-option
              value="${value}"
              index="${index}"
            ></bs-dropdown-option>`
        });
        jest.spyOn(page.rootInstance, 'id', 'get').mockReturnValue(id);
        const evSpy = jest.spyOn(page.rootInstance.optionselect, 'emit');
        fireEvent.click(page.root);
        expect(evSpy).toBeCalledWith({ id, index, value });
      });
    });
  });
  describe('Test component class logic', () => {
    let comp;
    beforeEach(() => {
      comp = new BsDropdownOption();
    });
    describe('onFocusChange()', () => {
      it('should focus the option when true', () => {
        const liEl = document.createElement('li');
        const focusMock = jest.fn();
        liEl.addEventListener('focus', focusMock);
        comp.option = liEl;
        comp.onFocusChange(true);
        expect(focusMock).toHaveBeenCalled();
      });
      it('should blur the option when false', () => {
        const liEl = document.createElement('li');
        const blurMock = jest.fn();
        liEl.addEventListener('blur', blurMock);
        comp.option = liEl;
        comp.onFocusChange(false);
        expect(blurMock).toHaveBeenCalled();
      });
    });
    describe('handleKeyDown()', () => {
      let selectedEvSpy;
      let id;
      let index;
      let value;
      beforeEach(() => {
        selectedEvSpy = jest.spyOn(comp.optionselect, 'emit');
        id = faker.random.alphaNumeric(10);
        index = Number(faker.random.numeric(1));
        value = faker.random.word();
        jest.spyOn(comp, 'id', 'get').mockReturnValue(id);
        comp.index = index;
        comp.value = value;
      });
      it('should not emit selected when not shown', () => {
        comp.shown = false;
        const kbEv = new KeyboardEvent('keydown', { key: 'Enter' });
        comp.handleKeyDown(kbEv);
        expect(selectedEvSpy).not.toHaveBeenCalled();
      });
      it('should emit selected option on space input', () => {
        comp.shown = true;
        const kbEv = new KeyboardEvent('keydown', { key: ' ' });
        comp.handleKeyDown(kbEv);
        expect(selectedEvSpy).toHaveBeenCalledWith({ id, index, value });
      });
      it('should emit selected option on enter input', () => {
        comp.shown = true;
        const kbEv = new KeyboardEvent('keydown', { key: 'Enter' });
        comp.handleKeyDown(kbEv);
        expect(selectedEvSpy).toHaveBeenCalledWith({ id, index, value });
      });
      it('should emit selected option on numpad enter input', () => {
        comp.shown = true;
        const kbEv = new KeyboardEvent('keydown', { key: 'NumpadEnter' });
        comp.handleKeyDown(kbEv);
        expect(selectedEvSpy).toHaveBeenCalledWith({ id, index, value });
      });
    });
    describe('get id()', () => {
      it('should return a properly formatted id', () => {
        const dropdownId = faker.random.alphaNumeric(10);
        const index = faker.random.numeric(1);
        comp.dropdownId = dropdownId;
        comp.index = Number(index);
        expect(comp.id).toBe(`${dropdownId}-option-${index}`);
      });
    });
  });
});
//# sourceMappingURL=bs-dropdown-option.spec.js.map
