Skip to content
Snippets Groups Projects
Commit 9ec2259e authored by Savas Vedova's avatar Savas Vedova
Browse files

Merge branch '431633-add-grouping-to-group-report' into 'master'

parents f0b79a75 ce780034
No related branches found
No related tags found
No related merge requests found
Pipeline #1090418196 failed
Pipeline: E2E Omnibus GitLab EE

#1090486454

    Pipeline: GitLab

    #1090438161

      Pipeline: E2E GDK

      #1090426372

        +1
        ---
        name: group_level_vulnerability_report_grouping
        introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/137778
        rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/432778
        milestone: '16.7'
        type: development
        group: group::threat insights
        default_enabled: false
        ......@@ -8,6 +8,9 @@ export default {
        VulnerabilityReportTabs,
        },
        inject: ['hasProjects'],
        provide: {
        isGroupVulnerabilityReport: true,
        },
        };
        </script>
        ......
        ......@@ -11,6 +11,7 @@ import { createAlert } from '~/alert';
        import countsQuery from 'ee/security_dashboard/graphql/queries/vulnerability_severities_count.query.graphql';
        import SummaryHighlights from 'ee/vue_shared/security_reports/components/summary_highlights.vue';
        import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
        import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
        import { __, s__ } from '~/locale';
        import { getIdFromGraphQLId } from '~/graphql_shared/utils';
        import { scrollToElement, contentTop } from '~/lib/utils/common_utils';
        ......@@ -54,10 +55,14 @@ export default {
        GlSprintf,
        UserCalloutDismisser,
        },
        mixins: [glFeatureFlagsMixin()],
        inject: {
        fullPath: {
        default: '',
        },
        isGroupVulnerabilityReport: {
        default: false,
        },
        isProjectVulnerabilityReport: {
        default: false,
        },
        ......@@ -109,7 +114,18 @@ export default {
        return this.filterDropdowns.includes(FILTERS.PROJECT);
        },
        shouldShowGroupByButton() {
        return this.isProjectVulnerabilityReport && this.isVisible;
        if (!this.isVisible) {
        return false;
        }
        if (
        this.isGroupVulnerabilityReport &&
        this.glFeatures.groupLevelVulnerabilityReportGrouping
        ) {
        return true;
        }
        return this.isProjectVulnerabilityReport;
        },
        groups() {
        if (!this.groupBy) {
        ......@@ -310,8 +326,8 @@ export default {
        const queryName = `groupCounts.${value}`;
        const variables = {
        fullPath: this.fullPath,
        isProject: true,
        isGroup: false,
        isProject: this.isProjectVulnerabilityReport,
        isGroup: this.isGroupVulnerabilityReport,
        isInstance: false,
        ...this.graphqlFilters,
        ...this.formatGroupFilters(value),
        ......@@ -329,8 +345,10 @@ export default {
        return variables;
        },
        update(data) {
        this.$set(this.groupCounts, value, data.project?.vulnerabilitySeveritiesCount);
        return data.project?.vulnerabilitySeveritiesCount;
        const level = this.isProjectVulnerabilityReport ? 'project' : 'group';
        this.$set(this.groupCounts, value, data[level]?.vulnerabilitySeveritiesCount);
        return data[level]?.vulnerabilitySeveritiesCount;
        },
        error() {
        createAlert({
        ......
        ......@@ -14,6 +14,7 @@ class VulnerabilitiesController < Groups::ApplicationController
        before_action do
        push_frontend_feature_flag(:activity_filter_has_mr, @project)
        push_frontend_feature_flag(:activity_filter_has_remediations, @project)
        push_frontend_feature_flag(:group_level_vulnerability_report_grouping, @project)
        end
        def index
        ......
        ......@@ -40,7 +40,9 @@ describe('Vulnerability report component', () => {
        fullPath,
        filterFn,
        scanners,
        isGroupVulnerabilityReport,
        isProjectVulnerabilityReport = true,
        glFeatures,
        shouldShowCallout = false,
        } = {}) => {
        router = new VueRouter({
        ......@@ -54,9 +56,11 @@ describe('Vulnerability report component', () => {
        apolloProvider,
        router,
        provide: {
        isGroupVulnerabilityReport,
        isProjectVulnerabilityReport,
        fullPath,
        scanners,
        glFeatures,
        },
        propsData: {
        query,
        ......@@ -212,13 +216,14 @@ describe('Vulnerability report component', () => {
        });
        });
        describe('group by', () => {
        describe.each`
        dashboardType
        ${DASHBOARD_TYPES.PROJECT}
        ${DASHBOARD_TYPES.GROUP}
        `('group by: $dashboardType', ({ dashboardType }) => {
        const counts = { critical: 1, high: 2, medium: 5, low: 4, info: 3, unknown: 6 };
        const getCountsRequestHandler = ({
        data = counts,
        dashboardType = DASHBOARD_TYPES.PROJECT,
        } = {}) => {
        const getCountsRequestHandler = ({ data = counts } = {}) => {
        return jest.fn().mockResolvedValue({
        data: {
        [dashboardType]: {
        ......@@ -249,10 +254,17 @@ describe('Vulnerability report component', () => {
        } = {}) => {
        createWrapper({
        apolloProvider: createMockApollo([[countsQuery, getCountsRequestHandler()]]),
        isProjectVulnerabilityReport: true,
        isProjectVulnerabilityReport: dashboardType === DASHBOARD_TYPES.PROJECT,
        isGroupVulnerabilityReport: dashboardType === DASHBOARD_TYPES.GROUP,
        fullPath: 'gitlab-org/gitlab',
        shouldShowCallout,
        scanners,
        glFeatures:
        DASHBOARD_TYPES.GROUP === dashboardType
        ? {
        groupLevelVulnerabilityReportGrouping: true,
        }
        : {},
        });
        // Reset filters
        ......@@ -267,26 +279,6 @@ describe('Vulnerability report component', () => {
        await waitForPromises();
        };
        it.each`
        isProjectVulnerabilityReport | isVisible | shouldDisplay
        ${false} | ${true} | ${false}
        ${true} | ${true} | ${true}
        ${true} | ${false} | ${false}
        `(
        'displays the group by button correctly ' +
        'project: $isProjectVulnerabilityReport, ' +
        'isVisible: $isVisible, ' +
        'should display: $shouldDisplay',
        ({ isProjectVulnerabilityReport, isVisible, shouldDisplay }) => {
        createWrapper({
        isProjectVulnerabilityReport,
        isVisible,
        });
        expect(findGroupByButton().exists()).toBe(shouldDisplay);
        },
        );
        it('displays the group by label', () => {
        createWrapperWithFilters();
        expect(wrapper.findByText('Group by:').exists()).toBe(true);
        ......
        0% Loading or .
        You are about to add 0 people to the discussion. Proceed with caution.
        Finish editing this message first!
        Please register or to comment