Commit 5dd18276 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch '345316-group-level-policies-list' into 'master'

Update policy list root file to be malleable

See merge request gitlab-org/gitlab!83911
parents 5b3f2d92 b18926b4
import initSecurityPoliciesList from 'ee/threat_monitoring/security_policies_list';
import { NAMESPACE_TYPES } from 'ee/threat_monitoring/constants';
initSecurityPoliciesList(
document.getElementById('js-group-security-policies-list'),
NAMESPACE_TYPES.GROUP,
);
import initSecurityPoliciesList from 'ee/threat_monitoring/security_policies_list';
import { NAMESPACE_TYPES } from 'ee/threat_monitoring/constants';
initSecurityPoliciesList();
initSecurityPoliciesList(
document.getElementById('js-security-policies-list'),
NAMESPACE_TYPES.PROJECT,
);
......@@ -9,14 +9,15 @@ import {
GlTooltipDirective,
} from '@gitlab/ui';
import { mapState, mapGetters } from 'vuex';
import { PREDEFINED_NETWORK_POLICIES } from 'ee/threat_monitoring/constants';
import { NAMESPACE_TYPES, PREDEFINED_NETWORK_POLICIES } from 'ee/threat_monitoring/constants';
import createFlash from '~/flash';
import { getTimeago } from '~/lib/utils/datetime_utility';
import { setUrlFragment, mergeUrlParams } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import networkPoliciesQuery from '../../graphql/queries/network_policies.query.graphql';
import scanExecutionPoliciesQuery from '../../graphql/queries/scan_execution_policies.query.graphql';
import projectScanExecutionPoliciesQuery from '../../graphql/queries/project_scan_execution_policies.query.graphql';
import groupScanExecutionPoliciesQuery from '../../graphql/queries/group_scan_execution_policies.query.graphql';
import scanResultPoliciesQuery from '../../graphql/queries/scan_result_policies.query.graphql';
import { getPolicyType } from '../../utils';
import { POLICY_TYPE_COMPONENT_OPTIONS, POLICY_TYPE_OPTIONS } from '../constants';
......@@ -26,6 +27,11 @@ import PolicyEnvironments from '../policy_environments.vue';
import PolicyTypeFilter from '../policy_type_filter.vue';
import NoPoliciesEmptyState from './no_policies_empty_state.vue';
const NAMESPACE_QUERY_DICT = {
[NAMESPACE_TYPES.PROJECT]: projectScanExecutionPoliciesQuery,
[NAMESPACE_TYPES.GROUP]: groupScanExecutionPoliciesQuery,
};
const createPolicyFetchError = ({ gqlError, networkError }) => {
const error =
gqlError?.message ||
......@@ -60,7 +66,7 @@ export default {
GlTooltip: GlTooltipDirective,
},
mixins: [glFeatureFlagMixin()],
inject: ['documentationPath', 'projectPath', 'newPolicyPath'],
inject: ['documentationPath', 'groupPath', 'projectPath', 'namespaceType', 'newPolicyPath'],
props: {
shouldUpdatePolicyList: {
type: Boolean,
......@@ -88,14 +94,20 @@ export default {
},
error: createPolicyFetchError,
skip() {
return !this.hasEnvironment || !this.shouldShowNetworkPolicies;
return (
!this.hasEnvironment ||
!this.shouldShowNetworkPolicies ||
this.namespaceType !== NAMESPACE_TYPES.PROJECT
);
},
},
scanExecutionPolicies: {
query: scanExecutionPoliciesQuery,
query() {
return NAMESPACE_QUERY_DICT[this.namespaceType];
},
variables() {
return {
fullPath: this.projectPath,
fullPath: this.projectPath || this.groupPath,
};
},
update(data) {
......@@ -114,6 +126,9 @@ export default {
return data?.project?.scanResultPolicies?.nodes ?? [];
},
error: createPolicyFetchError,
skip() {
return this.namespaceType !== NAMESPACE_TYPES.PROJECT;
},
},
},
data() {
......
......@@ -45,3 +45,8 @@ spec:
export const ALL_ENVIRONMENT_NAME = s__('ThreatMonitoring|All Environments');
export const PAGE_SIZE = 20;
export const NAMESPACE_TYPES = {
PROJECT: 'project',
GROUP: 'group',
};
query groupScanExecutionPolicies($fullPath: ID!) {
group(fullPath: $fullPath) @client {
id
scanExecutionPolicies {
nodes {
name
yaml
enabled
updatedAt
}
}
}
}
query scanExecutionPolicies($fullPath: ID!) {
query projectScanExecutionPolicies($fullPath: ID!) {
project(fullPath: $fullPath) {
id
scanExecutionPolicies {
......
......@@ -12,8 +12,7 @@ const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
});
export default () => {
const el = document.querySelector('#js-security-policies-list');
export default (el, namespaceType) => {
const {
assignedPolicyProject,
disableSecurityPolicyProject,
......@@ -22,6 +21,7 @@ export default () => {
emptyFilterSvgPath,
emptyListSvgPath,
documentationPath,
groupPath,
newPolicyPath,
projectPath,
} = el.dataset;
......@@ -52,6 +52,8 @@ export default () => {
projectPath,
emptyFilterSvgPath,
emptyListSvgPath,
groupPath,
namespaceType,
},
render(createElement) {
return createElement(SecurityPoliciesApp);
......
......@@ -2,4 +2,9 @@
- @content_wrapper_class = 'js-security-policies-container-wrapper'
#js-group-security-policies-list{ data: { group_path: group.full_path,
assigned_policy_project: 'null',
disable_security_policy_project: false.to_s,
new_policy_path: new_group_security_policy_path(group),
empty_filter_svg_path: image_path('illustrations/issues.svg'),
empty_list_svg_path: image_path('illustrations/security-dashboard_empty.svg'),
documentation_path: help_page_path('user/application_security/policies/index.md') } }
......@@ -5,9 +5,9 @@ import VueApollo from 'vue-apollo';
import { POLICY_TYPE_OPTIONS } from 'ee/threat_monitoring/components/constants';
import PoliciesList from 'ee/threat_monitoring/components/policies/policies_list.vue';
import PolicyDrawer from 'ee/threat_monitoring/components/policy_drawer/policy_drawer.vue';
import { PREDEFINED_NETWORK_POLICIES } from 'ee/threat_monitoring/constants';
import { NAMESPACE_TYPES, PREDEFINED_NETWORK_POLICIES } from 'ee/threat_monitoring/constants';
import networkPoliciesQuery from 'ee/threat_monitoring/graphql/queries/network_policies.query.graphql';
import scanExecutionPoliciesQuery from 'ee/threat_monitoring/graphql/queries/scan_execution_policies.query.graphql';
import projectScanExecutionPoliciesQuery from 'ee/threat_monitoring/graphql/queries/project_scan_execution_policies.query.graphql';
import scanResultPoliciesQuery from 'ee/threat_monitoring/graphql/queries/scan_result_policies.query.graphql';
import createStore from 'ee/threat_monitoring/store';
import createMockApollo from 'helpers/mock_apollo_helper';
......@@ -16,7 +16,7 @@ import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_help
import waitForPromises from 'helpers/wait_for_promises';
import {
networkPolicies,
scanExecutionPolicies,
projectScanExecutionPolicies,
scanResultPolicies,
} from '../../mocks/mock_apollo';
import {
......@@ -27,7 +27,8 @@ import {
Vue.use(VueApollo);
const fullPath = 'project/path';
const projectFullPath = 'project/path';
const groupFullPath = 'group/path';
const environments = [
{
id: 2,
......@@ -39,11 +40,13 @@ const environments = [
},
];
const networkPoliciesSpy = networkPolicies(mockNetworkPoliciesResponse);
const scanExecutionPoliciesSpy = scanExecutionPolicies(mockScanExecutionPoliciesResponse);
const projectScanExecutionPoliciesSpy = projectScanExecutionPolicies(
mockScanExecutionPoliciesResponse,
);
const scanResultPoliciesSpy = scanResultPolicies(mockScanResultPoliciesResponse);
const defaultRequestHandlers = {
networkPolicies: networkPoliciesSpy,
scanExecutionPolicies: scanExecutionPoliciesSpy,
projectScanExecutionPolicies: projectScanExecutionPoliciesSpy,
scanResultPolicies: scanResultPoliciesSpy,
};
const pendingHandler = jest.fn(() => new Promise(() => {}));
......@@ -86,13 +89,15 @@ describe('PoliciesList component', () => {
store,
provide: {
documentationPath: 'path/to/docs',
namespaceType: NAMESPACE_TYPES.PROJECT,
newPolicyPath: 'path/to/policy',
projectPath: fullPath,
groupPath: undefined,
projectPath: projectFullPath,
glFeatures: { scanResultPolicy: true },
},
apolloProvider: createMockApollo([
[networkPoliciesQuery, requestHandlers.networkPolicies],
[scanExecutionPoliciesQuery, requestHandlers.scanExecutionPolicies],
[projectScanExecutionPoliciesQuery, requestHandlers.projectScanExecutionPolicies],
[scanResultPoliciesQuery, requestHandlers.scanResultPolicies],
]),
stubs: {
......@@ -149,10 +154,13 @@ describe('PoliciesList component', () => {
it('fetches policies', () => {
expect(requestHandlers.networkPolicies).toHaveBeenCalledWith({
environmentId: environments[0].global_id,
fullPath,
fullPath: projectFullPath,
});
expect(requestHandlers.projectScanExecutionPolicies).toHaveBeenCalledWith({
fullPath: projectFullPath,
});
expect(requestHandlers.scanExecutionPolicies).toHaveBeenCalledWith({
fullPath,
expect(requestHandlers.scanResultPolicies).toHaveBeenCalledWith({
fullPath: projectFullPath,
});
});
......@@ -234,12 +242,12 @@ describe('PoliciesList component', () => {
});
it('does emit `update-policy-list` and refetch scan execution policies on `shouldUpdatePolicyList` change to `false`', async () => {
expect(scanExecutionPoliciesSpy).toHaveBeenCalledTimes(1);
expect(projectScanExecutionPoliciesSpy).toHaveBeenCalledTimes(1);
expect(wrapper.emitted('update-policy-list')).toBeUndefined();
wrapper.setProps({ shouldUpdatePolicyList: true });
await nextTick();
expect(wrapper.emitted('update-policy-list')).toStrictEqual([[false]]);
expect(scanExecutionPoliciesSpy).toHaveBeenCalledTimes(2);
expect(projectScanExecutionPoliciesSpy).toHaveBeenCalledTimes(2);
});
it('does not emit `update-policy-list` or refetch scan execution policies on `shouldUpdatePolicyList` change to `false`', async () => {
......@@ -248,7 +256,26 @@ describe('PoliciesList component', () => {
wrapper.setProps({ shouldUpdatePolicyList: false });
await nextTick();
expect(wrapper.emitted('update-policy-list')).toStrictEqual([[false]]);
expect(scanExecutionPoliciesSpy).toHaveBeenCalledTimes(2);
expect(projectScanExecutionPoliciesSpy).toHaveBeenCalledTimes(2);
});
});
describe('group-level policies', () => {
beforeEach(async () => {
mountShallowWrapper({
provide: {
groupPath: groupFullPath,
projectPath: undefined,
namespaceType: NAMESPACE_TYPES.GROUP,
},
});
await waitForPromises();
});
it('does not fetch policies', () => {
expect(requestHandlers.networkPolicies).not.toHaveBeenCalled();
expect(requestHandlers.projectScanExecutionPolicies).not.toHaveBeenCalled();
expect(requestHandlers.scanResultPolicies).not.toHaveBeenCalled();
});
});
......
......@@ -46,7 +46,7 @@ export const networkPolicies = (nodes) =>
},
});
export const scanExecutionPolicies = (nodes) =>
export const projectScanExecutionPolicies = (nodes) =>
jest.fn().mockResolvedValue({
data: {
project: {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment