{"size": 4641, "ext": "js", "max_stars_repo_path": "ee/spec/frontend/security_dashboard/components/vulnerability_severity_spec.js", "max_stars_repo_name": "dreaminplus/gitlab", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "ee/spec/frontend/security_dashboard/components/vulnerability_severity_spec.js", "max_issues_repo_name": "dreaminplus/gitlab", "max_issues_repo_issues_event_min_datetime": "2021-05-20T21:17:26.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-02T09:51:46.000Z", "max_forks_repo_path": "ee/spec/frontend/security_dashboard/components/vulnerability_severity_spec.js", "max_forks_repo_name": "dreaminzero-cell/gitlab", "max_forks_repo_forks_event_min_datetime": "2020-11-04T05:26:21.000Z", "max_forks_repo_forks_event_max_datetime": "2020-11-06T04:49:03.000Z"}
{"max_stars_count": null, "max_issues_count": 6, "max_forks_count": 3, "avg_line_length": 28.2987804878, "max_line_length": 103, "alphanum_fraction": 0.6209868563}
import Vuex from 'vuex';
import { mount, createLocalVue } from '@vue/test-utils';

import { GlLink } from '@gitlab/ui';

import { trimText } from 'helpers/text_helper';

import { Accordion, AccordionItem } from 'ee/vue_shared/components/accordion';
import VulnerabilitySeverity from 'ee/security_dashboard/components/vulnerability_severity.vue';
import { severityGroupTypes } from 'ee/security_dashboard/store/modules/vulnerable_projects/constants';

const localVue = createLocalVue();
localVue.use(Vuex);

describe('Vulnerability Severity component', () => {
  let actions;
  let getters;
  let store;
  let propsData;
  let wrapper;

  const getMockProject = () => ({
    fullPath: '/foo/bar',
    fullName: 'baz',
    mostSevereVulnerability: { level: 'qux', count: 10 },
  });

  const getMockSeverityGroups = ({ projects = [] } = {}) =>
    Object.keys(severityGroupTypes).reduce((acc, curr) => {
      acc[curr] = { type: curr, projects };
      return acc;
    }, {});

  const factory = () => {
    const state = {
      isLoading: false,
      projects: [],
    };

    propsData = {
      endpoint: 'http://foo.com',
    };

    actions = {
      fetchProjects: jest.fn(),
    };

    getters = {
      severityGroups: getMockSeverityGroups,
    };

    store = new Vuex.Store({
      modules: {
        vulnerableProjects: {
          namespaced: true,
          actions,
          getters,
          state,
        },
      },
    });

    wrapper = mount(VulnerabilitySeverity, {
      localVue,
      store,
      propsData,
    });
  };

  const accordion = () => wrapper.find(Accordion);
  const accordionItems = () => wrapper.findAll(AccordionItem);
  const firstAccordionItem = () => accordionItems().at(0);

  const hasAccordionItemForEachSeverityLevel = () =>
    expect(accordionItems().length).toBe(Object.keys(getMockSeverityGroups()).length);

  const hasEachAccordionItemDisabled = () =>
    accordionItems().wrappers.every(item => item.props('disabled'));

  beforeEach(factory);

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

    jest.restoreAllMocks();
  });

  describe('when being created', () => {
    it('dispatches the "fetchProjects" action with the given endpoint as an argument', () => {
      expect(actions.fetchProjects).toHaveBeenCalledTimes(1);
      expect(actions.fetchProjects.mock.calls[0][1]).toBe(propsData.endpoint);
    });
  });

  describe('while the data is being loaded', () => {
    beforeEach(() => {
      store.state.vulnerableProjects.isLoading = true;
      return wrapper.vm.$nextTick();
    });

    it('contains an accordion item with a loading state for each of the severity levels', () => {
      hasAccordionItemForEachSeverityLevel();

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

  describe('when the data has loaded', () => {
    it('matches snapshot', () => {
      expect(wrapper.element).toMatchSnapshot();
    });
    it('contains an accordion', () => {
      expect(accordion().exists()).toBe(true);
    });

    it('contains an accordion item for each of the severity levels', () => {
      hasAccordionItemForEachSeverityLevel();
    });

    it('sets accordion items to be disabled if its given severity level has no projects', () => {
      store.state.vulnerableProjects.projects = [];

      return wrapper.vm.$nextTick().then(() => {
        expect(hasEachAccordionItemDisabled()).toBe(true);
      });
    });

    it('does not set accordion items to be disabled if its given severity level has projects', () => {
      store.state.vulnerableProjects.projects = [getMockProject()];

      return wrapper.vm.$nextTick().then(() => {
        expect(hasEachAccordionItemDisabled()).toBe(false);
      });
    });

    it('links to a given project', () => {
      const mockProject = getMockProject();
      store.state.vulnerableProjects.projects = [mockProject];

      return wrapper.vm.$nextTick().then(() => {
        expect(
          firstAccordionItem()
            .find(GlLink)
            .attributes('href'),
        ).toContain(mockProject.fullPath);

        expect(firstAccordionItem().text()).toContain(mockProject.fullName);
      });
    });

    it('shows a count for the most severe vulnerability level', () => {
      const project = { mostSevereVulnerability: { level: 'critical', count: 10 } };
      store.state.vulnerableProjects.projects = [project];

      return wrapper.vm.$nextTick().then(() => {
        expect(trimText(wrapper.find({ ref: 'mostSevereCount' }).text())).toBe('10 Critical');
      });
    });
  });
});
