import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import VulnerabilityFindingModal from 'ee/security_dashboard/components/pipeline/vulnerability_finding_modal.vue';
import SolutionCard from 'ee/vue_shared/security_reports/components/solution_card_vuex.vue';
import VulnerabilityDetails from 'ee/vulnerabilities/components/vulnerability_details.vue';

const TEST_VULNERABILITY = {
  name: 'foo',
  solution: 'foo',
  hasMergeRequest: false,
  remediations: [{}],
};

describe('Vulnerability finding modal', () => {
  let wrapper;

  const createWrapper = (options = {}) =>
    shallowMount(VulnerabilityFindingModal, {
      propsData: {
        finding: TEST_VULNERABILITY,
      },
      ...options,
    });

  const findModal = () => wrapper.findComponent(GlModal);
  const findVulnerabilityDetails = () => wrapper.findComponent(VulnerabilityDetails);
  const findSolutionCard = () => wrapper.findComponent(SolutionCard);

  beforeEach(() => {
    wrapper = createWrapper();
  });

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

  describe('modal instance', () => {
    it('gets passed the correct props', () => {
      expect(findModal().props()).toMatchObject({
        title: TEST_VULNERABILITY.name,
        modalId: expect.any(String),
      });
    });

    it('makes the component emit "hide" when the modal gets closed', () => {
      expect(wrapper.emitted('hide')).toBeUndefined();

      findModal().vm.$emit('hide');

      expect(wrapper.emitted('hide')).toHaveLength(1);
    });
  });

  describe('finding details', () => {
    it('displays details about the given vulnerability finding', () => {
      expect(findVulnerabilityDetails().props('vulnerability')).toBe(TEST_VULNERABILITY);
    });
  });

  describe('solution card', () => {
    it('gets passed the correct props', () => {
      expect(findSolutionCard().props()).toMatchObject({
        solution: TEST_VULNERABILITY.solution,
        hasMr: TEST_VULNERABILITY.hasMergeRequest,
        remediation: TEST_VULNERABILITY.remediations[0],
      });
    });

    it.each`
      condition                                | expectedHasDownloadValue | vulnerabilityData
      ${'merge request and remediations diff'} | ${true}                  | ${{ hasMergeRequest: false, remediations: [{ diff: ['foo'] }] }}
      ${'merge request'}                       | ${false}                 | ${{ hasMergeRequest: true }}
      ${'no remediation'}                      | ${false}                 | ${{ remediations: [] }}
      ${'no remediation diff'}                 | ${false}                 | ${{ remediations: [{ diff: [] }] }}
    `(
      'gets passed the "hasDownload" prop as "$expectedHasDownloadValue" when the vulnerability has $condition',
      ({ vulnerabilityData, expectedHasDownloadValue }) => {
        wrapper = createWrapper({
          propsData: {
            finding: { ...TEST_VULNERABILITY, ...vulnerabilityData },
          },
        });

        expect(findSolutionCard().props('hasDownload')).toBe(expectedHasDownloadValue);
      },
    );
  });
});
