import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import VulnerabilityCount from 'ee/security_dashboard/components/shared/vulnerability_count.vue';
import VulnerabilityCountListLayout from 'ee/security_dashboard/components/shared/vulnerability_count_list_layout.vue';

describe('Vulnerabilities count list component', () => {
  let wrapper;

  const findAlert = () => wrapper.find(GlAlert);
  const findVulnerability = () => wrapper.findAll(VulnerabilityCount);

  const createWrapper = ({ propsData } = {}) => {
    return shallowMount(VulnerabilityCountListLayout, {
      propsData,
      stubs: {
        GlAlert,
      },
    });
  };

  afterEach(() => {
    wrapper.destroy();
  });

  describe('when loading', () => {
    it('passes the isLoading prop to the counts', () => {
      wrapper = createWrapper({ propsData: { isLoading: true, vulnerabilitiesCount: {} } });

      findVulnerability().wrappers.forEach((component) => {
        expect(component.props('isLoading')).toBe(true);
      });
    });
  });

  describe('when there are no counts', () => {
    beforeEach(() => {
      wrapper = createWrapper({ propsData: { vulnerabilitiesCount: {} } });
    });

    it.each`
      index | name
      ${0}  | ${'critical'}
      ${1}  | ${'high'}
      ${2}  | ${'medium'}
      ${3}  | ${'low'}
      ${4}  | ${'info'}
      ${5}  | ${'unknown'}
    `('shows 0 count for $name', ({ index, name }) => {
      const vulnerability = findVulnerability().at(index);
      expect(vulnerability.props('severity')).toBe(name);
      expect(vulnerability.props('count')).toBe(0);
    });
  });

  describe('when loaded and has a list of vulnerability counts', () => {
    const vulnerabilitiesCount = { critical: 5, medium: 3, info: 1, unknown: 2, low: 3, high: 8 };

    beforeEach(() => {
      wrapper = createWrapper({ propsData: { vulnerabilitiesCount } });
    });

    it('sets the isLoading prop false and passes it down', () => {
      findVulnerability().wrappers.forEach((component) => {
        expect(component.props('isLoading')).toBe(false);
      });
    });

    it.each`
      index | count                            | name
      ${0}  | ${vulnerabilitiesCount.critical} | ${'critical'}
      ${1}  | ${vulnerabilitiesCount.high}     | ${'high'}
      ${2}  | ${vulnerabilitiesCount.medium}   | ${'medium'}
      ${3}  | ${vulnerabilitiesCount.low}      | ${'low'}
      ${4}  | ${vulnerabilitiesCount.info}     | ${'info'}
      ${5}  | ${vulnerabilitiesCount.unknown}  | ${'unknown'}
    `('shows count for $name correctly', ({ index, count, name }) => {
      const vulnerability = findVulnerability().at(index);
      expect(vulnerability.props('severity')).toBe(name);
      expect(vulnerability.props('count')).toBe(count);
    });
  });

  describe('when loaded and has an error', () => {
    it('shows the error message', () => {
      wrapper = createWrapper({ propsData: { showError: true, vulnerabilitiesCount: {} } });
      expect(findAlert().text()).toBe(
        'Error fetching the vulnerability counts. Please check your network connection and try again.',
      );
    });
  });
});
