import { DOMWrapper, mount, VueWrapper } from '@vue/test-utils';
import MProgress from '@/components/progressbar/MProgress.vue';

const valueMin = 10;
const valueMax = 20;
const value = 15;
let wrapper: VueWrapper<any>;
let progressBarElement: DOMWrapper<HTMLDivElement>;

describe('min, max and current values', () => {
  beforeEach(() => {
    wrapper = mount(MProgress, {
      props: {
        valueMin,
        valueMax,
        value
      }
    });
    progressBarElement = wrapper.find('.mc-progressbar__indicator');
  });

  it('should set the min, max and current values', () => {
    expect(progressBarElement.attributes('aria-valuenow')).toEqual(String(value));
    expect(progressBarElement.attributes('aria-valuemin')).toEqual(String(valueMin));
    expect(progressBarElement.attributes('aria-valuemax')).toEqual(String(valueMax));
  });

  it('should be reactive to value changes', async () => {
    const newValue = 18;
    await wrapper.setProps({ value: newValue });
    expect(progressBarElement.attributes('aria-valuenow')).toEqual(String(newValue));
  });
});

describe('progress appearance', () => {
  beforeEach(() => {
    wrapper = mount(MProgress, {
      props: {
        valueMin,
        valueMax,
        value
      }
    });
    progressBarElement = wrapper.find('.mc-progressbar__indicator');
  });

  it('should display the correct width on the progressbar', () => {
    expect(progressBarElement.attributes('style')).toContain(('width: 50%'));
  });

  it('should display the correct width on the progressbar', async () => {
    await wrapper.setProps({ value: 18 });
    expect(progressBarElement.attributes('style')).toContain(('width: 80%'));
  });

  it('should ignore invalid progress value', async () => {
    await wrapper.setProps({ value: 18 });
    await wrapper.setProps({ value: 22 });
    expect(progressBarElement.attributes('style')).toContain(('width: 80%'));
  });
});

describe('A11Y', () => {
  function mountWithValueText(valueText: string | undefined) {
    wrapper = mount(MProgress, {
      props: {
        valueMin,
        valueMax,
        value,
        ...(valueText !== undefined ? { valueText } : {})
      }
    });
    progressBarElement = wrapper.find('.mc-progressbar__indicator');
  }

  it('should include an aria-valuetext when specified', () => {
    const valueText = 'progression of x %';
    mountWithValueText(valueText);
    expect(progressBarElement.attributes('aria-valuetext')).toEqual(valueText);
  });

  it('should ignore an empty aria-valuetext when specified', () => {
    mountWithValueText('');
    expect(progressBarElement.attributes('aria-valuetext')).toBeUndefined();
  });

  it('should not include an aria-valuetext when not specified', () => {
    mountWithValueText(undefined);

    expect(progressBarElement.attributes('aria-valuetext')).toBeUndefined();
  });
});
