import { shallowMount, mount } from '@vue/test-utils'; import Vue from 'vue'; import Vuex from 'vuex'; import { GlEmptyState, GlLoadingIcon, GlTab, GlTabs, GlAlert, GlDeprecatedBadge as GlBadge, } from '@gitlab/ui'; import { TEST_HOST } from 'helpers/test_constants'; import setWindowLocation from 'helpers/set_window_location_helper'; import { REPORT_STATUS } from 'ee/license_compliance/store/modules/list/constants'; import LicenseComplianceApp from 'ee/license_compliance/components/app.vue'; import DetectedLicensesTable from 'ee/license_compliance/components/detected_licenses_table.vue'; import PipelineInfo from 'ee/license_compliance/components/pipeline_info.vue'; import LicenseManagement from 'ee/vue_shared/license_compliance/license_management.vue'; import * as getters from 'ee/license_compliance/store/modules/list/getters'; import { approvedLicense, blacklistedLicense, } from 'ee_jest/vue_shared/license_compliance/mock_data'; import { LICENSE_APPROVAL_CLASSIFICATION } from 'ee/vue_shared/license_compliance/constants'; Vue.use(Vuex); let wrapper; const readLicensePoliciesEndpoint = `${TEST_HOST}/license_management`; const managedLicenses = [approvedLicense, blacklistedLicense]; const licenses = [{}, {}]; const emptyStateSvgPath = '/'; const documentationPath = '/'; const noop = () => {}; const createComponent = ({ state, props, options }) => { const fakeStore = new Vuex.Store({ modules: { licenseManagement: { namespaced: true, state: { managedLicenses, }, getters: { isAddingNewLicense: () => false, hasPendingLicenses: () => false, isLicenseBeingUpdated: () => () => false, }, actions: { fetchManagedLicenses: noop, setLicenseApproval: noop, }, }, licenseList: { namespaced: true, state: { licenses, reportInfo: { jobPath: '/', generatedAt: '', }, ...state, }, actions: { fetchLicenses: noop, }, getters, }, }, }); const mountFunc = options && options.mount ? mount : shallowMount; wrapper = mountFunc(LicenseComplianceApp, { propsData: { emptyStateSvgPath, documentationPath, readLicensePoliciesEndpoint, ...props, }, ...options, store: fakeStore, }); }; const findByTestId = testId => wrapper.find(`[data-testid="${testId}"]`); describe('Project Licenses', () => { afterEach(() => { wrapper.destroy(); wrapper = null; }); describe('when loading', () => { beforeEach(() => { createComponent({ state: { initialized: false }, }); }); it('shows the loading component', () => { expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); it('does not show the empty state component', () => { expect(wrapper.find(GlEmptyState).exists()).toBe(false); }); it('does not show the list of detected in project licenses', () => { expect(wrapper.find(DetectedLicensesTable).exists()).toBe(false); }); it('does not show the list of license policies', () => { expect(wrapper.find(LicenseManagement).exists()).toBe(false); }); it('does not render any tabs', () => { expect(wrapper.find(GlTabs).exists()).toBe(false); expect(wrapper.find(GlTab).exists()).toBe(false); }); }); describe('when empty state', () => { beforeEach(() => { createComponent({ state: { initialized: true, reportInfo: { jobPath: '/', generatedAt: '', status: REPORT_STATUS.jobNotSetUp, }, }, }); }); it('shows the empty state component', () => { expect(wrapper.find(GlEmptyState).exists()).toBe(true); }); it('does not show the loading component', () => { expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); }); it('does not show the list of detected in project licenses', () => { expect(wrapper.find(DetectedLicensesTable).exists()).toBe(false); }); it('does not show the list of license policies', () => { expect(wrapper.find(LicenseManagement).exists()).toBe(false); }); it('does not render any tabs', () => { expect(wrapper.find(GlTabs).exists()).toBe(false); expect(wrapper.find(GlTab).exists()).toBe(false); }); }); describe('when licensePolicyList feature flag is enabled', () => { beforeEach(() => { createComponent({ state: { initialized: true, reportInfo: { jobPath: '/', generatedAt: '', status: REPORT_STATUS.ok, }, }, options: { provide: { glFeatures: { licensePolicyList: true }, }, }, }); }); it('does not render a policy violations alert', () => { expect(wrapper.find(GlAlert).exists()).toBe(false); }); it('renders a "Detected in project" tab and a "Policies" tab', () => { expect(wrapper.find(GlTabs).exists()).toBe(true); expect(wrapper.find(GlTab).exists()).toBe(true); expect(wrapper.findAll(GlTab)).toHaveLength(2); }); it('it renders the "Detected in project" table', () => { expect(wrapper.find(DetectedLicensesTable).exists()).toBe(true); }); it('it renders the "Policies" table', () => { expect(wrapper.find(LicenseManagement).exists()).toBe(true); }); it('renders the pipeline info', () => { expect(wrapper.find(PipelineInfo).exists()).toBe(true); }); describe.each` givenLocationHash | expectedActiveTab ${'#licenses'} | ${'licenses'} ${'#policies'} | ${'policies'} `( 'when window.location contains the hash "$givenLocationHash"', ({ givenLocationHash, expectedActiveTab }) => { const originalLocation = window.location; beforeEach(() => { setWindowLocation(`http://foo.com/index${givenLocationHash}`); createComponent({ state: { initialized: true, isLoading: false, licenses: [ { name: 'MIT', classification: LICENSE_APPROVAL_CLASSIFICATION.DENIED, components: [], }, ], pageInfo: 1, }, options: { provide: { glFeatures: { licensePolicyList: true }, }, mount: true, }, }); }); afterEach(() => { window.location = originalLocation; }); it(`sets the active tab to be "${expectedActiveTab}"`, () => { expect(findByTestId(`${expectedActiveTab}Tab`).classes()).toContain('active'); }); }, ); describe('when the tabs are rendered', () => { const pageInfo = { total: 1, }; beforeEach(() => { createComponent({ state: { initialized: true, isLoading: false, licenses: [ { name: 'MIT', classification: LICENSE_APPROVAL_CLASSIFICATION.DENIED, components: [], }, ], reportInfo: { jobPath: '/', generatedAt: '', status: REPORT_STATUS.ok, }, pageInfo, }, options: { provide: { glFeatures: { licensePolicyList: true }, }, mount: true, }, }); }); it.each` givenActiveTab | expectedLocationHash ${'policies'} | ${'#policies'} ${'licenses'} | ${'#licenses'} `( 'sets the location hash to "$expectedLocationHash" when the "$givenTab" tab is activate', ({ givenActiveTab, expectedLocationHash }) => { findByTestId(`${givenActiveTab}TabTitle`).trigger('click'); return wrapper.vm.$nextTick().then(() => { expect(window.location.hash).toBe(expectedLocationHash); }); }, ); it('it renders the correct count in "Detected in project" tab', () => { expect( wrapper .findAll(GlBadge) .at(0) .text(), ).toBe(pageInfo.total.toString()); }); it('it renders the correct count in "Policies" tab', () => { expect( wrapper .findAll(GlBadge) .at(1) .text(), ).toBe(managedLicenses.length.toString()); }); }); describe('when there are policy violations', () => { beforeEach(() => { createComponent({ state: { initialized: true, licenses: [{ classification: LICENSE_APPROVAL_CLASSIFICATION.DENIED }], }, }); }); it('renders a policy violations alert', () => { expect(wrapper.find(GlAlert).exists()).toBe(true); expect(wrapper.find(GlAlert).text()).toContain( "Detected licenses that are out-of-compliance with the project's assigned policies", ); }); }); }); describe('when licensePolicyList feature flag is disabled', () => { beforeEach(() => { createComponent({ state: { initialized: true, reportInfo: { jobPath: '/', generatedAt: '', status: REPORT_STATUS.ok, }, }, options: { provide: { glFeatures: { licensePolicyList: false }, }, }, }); }); it('only renders the "Detected in project" table', () => { expect(wrapper.find(DetectedLicensesTable).exists()).toBe(true); expect(wrapper.find(LicenseManagement).exists()).toBe(false); }); it('renders no "Policies" table', () => { expect(wrapper.find(GlTabs).exists()).toBe(false); expect(wrapper.find(GlTab).exists()).toBe(false); }); it('renders the pipeline info', () => { expect(wrapper.find(PipelineInfo).exists()).toBe(true); }); it('renders no tabs', () => { expect(wrapper.find(GlTabs).exists()).toBe(false); expect(wrapper.find(GlTab).exists()).toBe(false); }); }); });