import { mount } from '@vue/test-utils';
import createState from 'ee/vue_shared/security_reports/store/state';
import VulnerabilityDetails from 'ee/vue_shared/security_reports/components/vulnerability_details.vue';
import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_badge.vue';
import SafeLink from 'ee/vue_shared/components/safe_link.vue';
import { TEST_HOST } from 'helpers/test_constants';

describe('VulnerabilityDetails component', () => {
  let wrapper;

  const componentFactory = (options = {}) => {
    wrapper = mount(VulnerabilityDetails, {
      ...options,
    });
  };

  const expectSafeLink = (link, { href, text }) => {
    expect(link.is(SafeLink)).toBe(true);
    expect(link.props('href')).toBe(href);
    expect(link.text()).toBe(text);
  };

  it('renders severity with a badge', () => {
    const value = 'critical';
    componentFactory({ propsData: { details: { severity: { value } } } });
    const badge = wrapper.find(SeverityBadge);

    expect(badge.props('severity')).toBe(value);
  });

  it('renders link fields with link', () => {
    const details = {
      somefield: {
        value: 'foo',
        url: `${TEST_HOST}/bar`,
        isLink: true,
      },
    };

    componentFactory({ propsData: { details } });

    expectSafeLink(wrapper.find('.js-link-somefield'), {
      href: `${TEST_HOST}/bar`,
      text: 'foo',
    });
  });

  it('renders wrapped file paths', () => {
    const value = '/some/file/path';
    const valueWrapped = '/<wbr>some/<wbr>file/<wbr>path';
    const details = {
      file: {
        value,
        url: `${TEST_HOST}/bar`,
        isLink: true,
      },
    };
    componentFactory({ propsData: { details } });
    expect(wrapper.find(SafeLink).html()).toMatch(valueWrapped);
  });

  it('escapes wrapped file paths', () => {
    const value = '/unsafe/path<script></script>';
    const valueWrapped = '/<wbr>unsafe/<wbr>path&lt;script&gt;&lt;/<wbr>script&gt;';
    const details = {
      file: {
        value,
        url: `${TEST_HOST}/bar`,
        isLink: true,
      },
    };
    componentFactory({ propsData: { details } });
    expect(wrapper.find(SafeLink).html()).toMatch(valueWrapped);
  });

  describe('does not render XSS links', () => {
    // eslint-disable-next-line no-script-url
    const badUrl = 'javascript:alert("")';

    beforeEach(() => {
      const details = createState().modal.data;

      details.file.value = 'badFile.lock';
      details.file.url = badUrl;
      details.links.value = [
        {
          url: badUrl,
        },
      ];
      details.identifiers.value = [
        {
          type: 'CVE',
          name: 'BAD_URL',
          url: badUrl,
        },
      ];
      details.instances.value = [
        {
          param: 'X-Content-Type-Options',
          method: 'GET',
          uri: badUrl,
        },
      ];

      componentFactory({ propsData: { details } });
    });

    it('for the link field', () => {
      expectSafeLink(wrapper.find('.js-link-links'), {
        href: badUrl,
        text: badUrl,
      });
    });

    it('for the identifiers field', () => {
      expectSafeLink(wrapper.find('.js-link-identifiers'), {
        href: badUrl,
        text: 'BAD_URL',
      });
    });

    it('for the file field', () => {
      expectSafeLink(wrapper.find('.js-link-file'), {
        href: badUrl,
        text: 'badFile.lock',
      });
    });

    it('for the instances field', () => {
      expectSafeLink(wrapper.find('.report-block-list-issue-description-link .break-link'), {
        href: badUrl,
        text: badUrl,
      });
    });
  });

  describe('with instances', () => {
    beforeEach(() => {
      const details = {
        instances: {
          value: [
            { uri: 'http://192.168.32.236:3001/explore?sort=latest_activity_desc' },
            { uri: 'http://192.168.32.236:3001/help/user/group/subgroups/index.md' },
          ],
        },
      };

      componentFactory({ propsData: { details } });
    });

    it('renders instances list', () => {
      const instances = wrapper.findAll('.report-block-list li').wrappers;

      expect(instances[0].text()).toContain(
        'http://192.168.32.236:3001/explore?sort=latest_activity_desc',
      );

      expect(instances[1].text()).toContain(
        'http://192.168.32.236:3001/help/user/group/subgroups/index.md',
      );
    });
  });
});
