Commit 42e1042c authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '321258-remove-frontend-portion' into 'master'

Remove frontend for security orchestration feature flag

See merge request gitlab-org/gitlab!71515
parents c26f6221 26e042ca
...@@ -2,10 +2,8 @@ ...@@ -2,10 +2,8 @@
import { GlIcon, GlLink, GlPopover, GlTabs, GlTab } from '@gitlab/ui'; import { GlIcon, GlLink, GlPopover, GlTabs, GlTab } from '@gitlab/ui';
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import Alerts from './alerts/alerts.vue'; import Alerts from './alerts/alerts.vue';
import NoEnvironmentEmptyState from './no_environment_empty_state.vue'; import NoEnvironmentEmptyState from './no_environment_empty_state.vue';
import PolicyList from './policy_list.vue';
import ThreatMonitoringFilters from './threat_monitoring_filters.vue'; import ThreatMonitoringFilters from './threat_monitoring_filters.vue';
import ThreatMonitoringSection from './threat_monitoring_section.vue'; import ThreatMonitoringSection from './threat_monitoring_section.vue';
...@@ -20,10 +18,8 @@ export default { ...@@ -20,10 +18,8 @@ export default {
Alerts, Alerts,
ThreatMonitoringFilters, ThreatMonitoringFilters,
ThreatMonitoringSection, ThreatMonitoringSection,
PolicyList,
NoEnvironmentEmptyState, NoEnvironmentEmptyState,
}, },
mixins: [glFeatureFlagMixin()],
inject: ['documentationPath'], inject: ['documentationPath'],
props: { props: {
defaultEnvironmentId: { defaultEnvironmentId: {
...@@ -48,11 +44,6 @@ export default { ...@@ -48,11 +44,6 @@ export default {
isSetUpMaybe: this.isValidEnvironmentId(this.defaultEnvironmentId), isSetUpMaybe: this.isValidEnvironmentId(this.defaultEnvironmentId),
}; };
}, },
computed: {
shouldShowPolicies() {
return !this.glFeatures.securityOrchestrationPoliciesConfiguration;
},
},
created() { created() {
if (this.isSetUpMaybe) { if (this.isSetUpMaybe) {
this.setCurrentEnvironmentId(this.defaultEnvironmentId); this.setCurrentEnvironmentId(this.defaultEnvironmentId);
...@@ -101,19 +92,6 @@ export default { ...@@ -101,19 +92,6 @@ export default {
> >
<alerts /> <alerts />
</gl-tab> </gl-tab>
<gl-tab
v-if="shouldShowPolicies"
ref="policyTab"
:title="s__('ThreatMonitoring|Policies')"
data-qa-selector="policies_tab"
>
<no-environment-empty-state v-if="!isSetUpMaybe" />
<policy-list
v-else
:documentation-path="documentationPath"
:new-policy-path="newPolicyPath"
/>
</gl-tab>
<gl-tab <gl-tab
:title="s__('ThreatMonitoring|Statistics')" :title="s__('ThreatMonitoring|Statistics')"
data-testid="threat-monitoring-statistics-tab" data-testid="threat-monitoring-statistics-tab"
...@@ -123,7 +101,7 @@ export default { ...@@ -123,7 +101,7 @@ export default {
<threat-monitoring-filters /> <threat-monitoring-filters />
<threat-monitoring-section <threat-monitoring-section
ref="policySection" data-testid="threat-monitoring-statistics-section"
store-namespace="threatMonitoringNetworkPolicy" store-namespace="threatMonitoringNetworkPolicy"
:title="s__('ThreatMonitoring|Container Network Policy')" :title="s__('ThreatMonitoring|Container Network Policy')"
:subtitle="s__('ThreatMonitoring|Packet Activity')" :subtitle="s__('ThreatMonitoring|Packet Activity')"
......
<script> <script>
import { GlAlert, GlFormGroup, GlFormSelect } from '@gitlab/ui'; import { GlAlert, GlFormGroup, GlFormSelect } from '@gitlab/ui';
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { POLICY_TYPE_COMPONENT_OPTIONS } from '../constants'; import { POLICY_TYPE_COMPONENT_OPTIONS } from '../constants';
import EnvironmentPicker from '../environment_picker.vue'; import EnvironmentPicker from '../environment_picker.vue';
import NetworkPolicyEditor from './network_policy/network_policy_editor.vue'; import NetworkPolicyEditor from './network_policy/network_policy_editor.vue';
...@@ -16,7 +15,6 @@ export default { ...@@ -16,7 +15,6 @@ export default {
NetworkPolicyEditor, NetworkPolicyEditor,
ScanExecutionPolicyEditor, ScanExecutionPolicyEditor,
}, },
mixins: [glFeatureFlagMixin()],
inject: ['policyType'], inject: ['policyType'],
props: { props: {
assignedPolicyProject: { assignedPolicyProject: {
...@@ -58,7 +56,7 @@ export default { ...@@ -58,7 +56,7 @@ export default {
); );
}, },
shouldAllowPolicyTypeSelection() { shouldAllowPolicyTypeSelection() {
return !this.existingPolicy && this.glFeatures.securityOrchestrationPoliciesConfiguration; return !this.existingPolicy;
}, },
}, },
created() { created() {
......
<script>
import {
GlTable,
GlEmptyState,
GlButton,
GlAlert,
GlSprintf,
GlLink,
GlIcon,
GlTooltipDirective,
} from '@gitlab/ui';
import { flatten } from 'lodash';
import { mapState, mapGetters } from 'vuex';
import { 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 networkPoliciesQuery from '../graphql/queries/network_policies.query.graphql';
import scanExecutionPoliciesQuery from '../graphql/queries/scan_execution_policies.query.graphql';
import { getPolicyType } from '../utils';
import { POLICY_TYPE_OPTIONS } from './constants';
import EnvironmentPicker from './environment_picker.vue';
import PolicyDrawer from './policy_drawer/policy_drawer.vue';
import PolicyEnvironments from './policy_environments.vue';
import PolicyTypeFilter from './policy_type_filter.vue';
const createPolicyFetchError = ({ gqlError, networkError }) => {
const error =
gqlError?.message ||
networkError?.message ||
s__('NetworkPolicies|Something went wrong, unable to fetch policies');
createFlash({
message: error,
});
};
const getPoliciesWithType = (policies, policyType) =>
policies.map((policy) => ({
...policy,
policyType,
}));
export default {
components: {
GlTable,
GlEmptyState,
GlButton,
GlAlert,
GlSprintf,
GlLink,
GlIcon,
EnvironmentPicker,
PolicyTypeFilter,
PolicyDrawer,
PolicyEnvironments,
},
directives: {
GlTooltip: GlTooltipDirective,
},
inject: ['projectPath'],
props: {
documentationPath: {
type: String,
required: true,
},
newPolicyPath: {
type: String,
required: true,
},
},
apollo: {
networkPolicies: {
query: networkPoliciesQuery,
variables() {
return {
fullPath: this.projectPath,
environmentId: this.allEnvironments ? null : this.currentEnvironmentGid,
};
},
update(data) {
const policies = data?.project?.networkPolicies?.nodes ?? [];
const predefined = PREDEFINED_NETWORK_POLICIES.filter(
({ name }) => !policies.some((policy) => name === policy.name),
);
return [...policies, ...predefined];
},
error: createPolicyFetchError,
skip() {
return this.isLoadingEnvironments || !this.shouldShowNetworkPolicies;
},
},
scanExecutionPolicies: {
query: scanExecutionPoliciesQuery,
variables() {
return {
fullPath: this.projectPath,
};
},
update(data) {
return data?.project?.scanExecutionPolicies?.nodes ?? [];
},
error: createPolicyFetchError,
},
},
data() {
return {
selectedPolicy: null,
networkPolicies: [],
scanExecutionPolicies: [],
selectedPolicyType: POLICY_TYPE_OPTIONS.ALL.value,
};
},
computed: {
...mapState('threatMonitoring', [
'currentEnvironmentId',
'allEnvironments',
'isLoadingEnvironments',
]),
...mapGetters('threatMonitoring', ['currentEnvironmentGid']),
allPolicyTypes() {
return {
[POLICY_TYPE_OPTIONS.POLICY_TYPE_NETWORK.value]: this.networkPolicies,
[POLICY_TYPE_OPTIONS.POLICY_TYPE_SCAN_EXECUTION.value]: this.scanExecutionPolicies,
};
},
documentationFullPath() {
return setUrlFragment(this.documentationPath, 'container-network-policy');
},
shouldShowNetworkPolicies() {
return [
POLICY_TYPE_OPTIONS.ALL.value,
POLICY_TYPE_OPTIONS.POLICY_TYPE_NETWORK.value,
].includes(this.selectedPolicyType);
},
policies() {
const policyTypes =
this.selectedPolicyType === POLICY_TYPE_OPTIONS.ALL.value
? Object.keys(this.allPolicyTypes)
: [this.selectedPolicyType];
const policies = policyTypes.map((type) =>
getPoliciesWithType(this.allPolicyTypes[type], POLICY_TYPE_OPTIONS[type].text),
);
return flatten(policies);
},
isLoadingPolicies() {
return (
this.isLoadingEnvironments ||
this.$apollo.queries.networkPolicies.loading ||
this.$apollo.queries.scanExecutionPolicies.loading
);
},
hasSelectedPolicy() {
return Boolean(this.selectedPolicy);
},
hasAutoDevopsPolicy() {
return Boolean(this.networkPolicies?.some((policy) => policy.fromAutoDevops));
},
editPolicyPath() {
return this.hasSelectedPolicy
? mergeUrlParams(
!this.selectedPolicy.kind
? { environment_id: this.currentEnvironmentId }
: { environment_id: this.currentEnvironmentId, kind: this.selectedPolicy.kind },
this.newPolicyPath.replace('new', `${this.selectedPolicy.name}/edit`),
)
: '';
},
policyType() {
// eslint-disable-next-line no-underscore-dangle
return this.selectedPolicy ? getPolicyType(this.selectedPolicy.__typename) : '';
},
fields() {
const environments = {
key: 'environments',
label: s__('SecurityPolicies|Environment(s)'),
};
const fields = [
{
key: 'status',
label: '',
thClass: 'gl-w-3',
tdAttr: {
'data-testid': 'policy-status-cell',
},
},
{
key: 'name',
label: __('Name'),
thClass: 'gl-w-half',
},
{
key: 'policyType',
label: s__('SecurityPolicies|Policy type'),
sortable: true,
},
{
key: 'updatedAt',
label: __('Last modified'),
sortable: true,
},
];
// Adds column 'environments' only while 'all environments' option is selected
if (this.allEnvironments) fields.splice(2, 0, environments);
return fields;
},
},
methods: {
getTimeAgoString(updatedAt) {
if (!updatedAt) return '';
return getTimeago().format(updatedAt);
},
presentPolicyDrawer(rows) {
if (rows.length === 0) return;
const [selectedPolicy] = rows;
this.selectedPolicy = selectedPolicy;
},
deselectPolicy() {
this.selectedPolicy = null;
const bTable = this.$refs.policiesTable.$children[0];
bTable.clearSelected();
},
},
i18n: {
emptyStateDescription: s__(
`NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints.`,
),
autodevopsNoticeDescription: s__(
`NetworkPolicies|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}.`,
),
statusEnabled: __('Enabled'),
statusDisabled: __('Disabled'),
},
};
</script>
<template>
<div>
<gl-alert
v-if="hasAutoDevopsPolicy"
data-testid="autodevopsAlert"
variant="info"
:dismissible="false"
class="gl-mb-3"
>
<gl-sprintf :message="$options.i18n.autodevopsNoticeDescription">
<template #monospaced="{ content }">
<span class="gl-font-monospace">{{ content }}</span>
</template>
<template #link="{ content }">
<gl-link :href="documentationFullPath">{{ content }}</gl-link>
</template>
</gl-sprintf>
</gl-alert>
<div class="pt-3 px-3 bg-gray-light">
<div class="row gl-justify-content-space-between gl-align-items-center">
<div class="col-12 col-sm-8 col-md-6 col-lg-5 row">
<policy-type-filter
v-model="selectedPolicyType"
class="col-6"
data-testid="policy-type-filter"
/>
<environment-picker ref="environmentsPicker" class="col-6" :include-all="true" />
</div>
<div class="col-sm-auto">
<gl-button
category="secondary"
variant="info"
:href="newPolicyPath"
data-testid="new-policy"
>{{ s__('NetworkPolicies|New policy') }}</gl-button
>
</div>
</div>
</div>
<gl-table
ref="policiesTable"
:busy="isLoadingPolicies"
:items="policies"
:fields="fields"
sort-icon-left
sort-by="updatedAt"
sort-desc
head-variant="white"
stacked="md"
thead-class="gl-text-gray-900 border-bottom"
tbody-class="gl-text-gray-900"
show-empty
hover
selectable
select-mode="single"
selected-variant="primary"
@row-selected="presentPolicyDrawer"
>
<template #cell(status)="value">
<gl-icon
v-if="value.item.enabled"
v-gl-tooltip="$options.i18n.statusEnabled"
:aria-label="$options.i18n.statusEnabled"
name="check-circle-filled"
class="gl-text-green-700"
/>
<span v-else class="gl-sr-only">{{ $options.i18n.statusDisabled }}</span>
</template>
<template #cell(environments)="value">
<policy-environments :environments="value.item.environments" />
</template>
<template #cell(updatedAt)="value">
{{ getTimeAgoString(value.item.updatedAt) }}
</template>
<template #empty>
<slot name="empty-state">
<gl-empty-state
ref="tableEmptyState"
:title="s__('NetworkPolicies|No policies detected')"
:description="$options.i18n.emptyStateDescription"
:primary-button-link="documentationFullPath"
:primary-button-text="__('Learn more')"
/>
</slot>
</template>
</gl-table>
<policy-drawer
:open="hasSelectedPolicy"
container-class=".js-threat-monitoring-container-wrapper"
:policy="selectedPolicy"
:policy-type="policyType"
:edit-policy-path="editPolicyPath"
data-testid="policyDrawer"
@close="deselectPolicy"
/>
</div>
</template>
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ThreatMonitoringApp component given there is a default environment with data renders the network policy section 1`] = ` exports[`ThreatMonitoringApp component given there is a default environment with data renders the statistics section 1`] = `
<threat-monitoring-section-stub <threat-monitoring-section-stub
anomaloustitle="Dropped Packets" anomaloustitle="Dropped Packets"
chartemptystatesvgpath="/network-policy-no-data-svg" chartemptystatesvgpath="/network-policy-no-data-svg"
chartemptystatetext="Container Network Policies are not installed or have been disabled. To view this data, ensure your Network Policies are installed and enabled for your cluster." chartemptystatetext="Container Network Policies are not installed or have been disabled. To view this data, ensure your Network Policies are installed and enabled for your cluster."
chartemptystatetitle="Container NetworkPolicies not detected" chartemptystatetitle="Container NetworkPolicies not detected"
data-testid="threat-monitoring-statistics-section"
documentationanchor="container-network-policy" documentationanchor="container-network-policy"
documentationpath="/docs" documentationpath="/docs"
nominaltitle="Total Packets" nominaltitle="Total Packets"
...@@ -15,16 +16,3 @@ exports[`ThreatMonitoringApp component given there is a default environment with ...@@ -15,16 +16,3 @@ exports[`ThreatMonitoringApp component given there is a default environment with
ylegend="Operations Per Second" ylegend="Operations Per Second"
/> />
`; `;
exports[`ThreatMonitoringApp component given there is a default environment with data renders the network policy tab 1`] = `
<gl-tab-stub
data-qa-selector="policies_tab"
title="Policies"
titlelinkclass=""
>
<policy-list-stub
documentationpath="/docs"
newpolicypath="/policy/new"
/>
</gl-tab-stub>
`;
...@@ -2,7 +2,6 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -2,7 +2,6 @@ import { shallowMount } from '@vue/test-utils';
import ThreatMonitoringAlerts from 'ee/threat_monitoring/components/alerts/alerts.vue'; import ThreatMonitoringAlerts from 'ee/threat_monitoring/components/alerts/alerts.vue';
import ThreatMonitoringApp from 'ee/threat_monitoring/components/app.vue'; import ThreatMonitoringApp from 'ee/threat_monitoring/components/app.vue';
import NoEnvironmentEmptyState from 'ee/threat_monitoring/components/no_environment_empty_state.vue'; import NoEnvironmentEmptyState from 'ee/threat_monitoring/components/no_environment_empty_state.vue';
import PolicyList from 'ee/threat_monitoring/components/policy_list.vue';
import ThreatMonitoringFilters from 'ee/threat_monitoring/components/threat_monitoring_filters.vue'; import ThreatMonitoringFilters from 'ee/threat_monitoring/components/threat_monitoring_filters.vue';
import createStore from 'ee/threat_monitoring/store'; import createStore from 'ee/threat_monitoring/store';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
...@@ -49,12 +48,10 @@ describe('ThreatMonitoringApp component', () => { ...@@ -49,12 +48,10 @@ describe('ThreatMonitoringApp component', () => {
); );
}; };
const findAlertsView = () => wrapper.find(ThreatMonitoringAlerts); const findAlertsView = () => wrapper.findComponent(ThreatMonitoringAlerts);
const findPolicyList = () => wrapper.find(PolicyList); const findFilters = () => wrapper.findComponent(ThreatMonitoringFilters);
const findFilters = () => wrapper.find(ThreatMonitoringFilters); const findStatisticsSection = () => wrapper.findByTestId('threat-monitoring-statistics-section');
const findPolicySection = () => wrapper.find({ ref: 'policySection' }); const findNoEnvironmentEmptyState = () => wrapper.findComponent(NoEnvironmentEmptyState);
const findNoEnvironmentEmptyStates = () => wrapper.findAll(NoEnvironmentEmptyState);
const findPolicyTab = () => wrapper.find({ ref: 'policyTab' });
const findAlertTab = () => wrapper.findByTestId('threat-monitoring-alerts-tab'); const findAlertTab = () => wrapper.findByTestId('threat-monitoring-alerts-tab');
const findStatisticsTab = () => wrapper.findByTestId('threat-monitoring-statistics-tab'); const findStatisticsTab = () => wrapper.findByTestId('threat-monitoring-statistics-tab');
...@@ -80,20 +77,16 @@ describe('ThreatMonitoringApp component', () => { ...@@ -80,20 +77,16 @@ describe('ThreatMonitoringApp component', () => {
}); });
it('shows the "no environment" empty state', () => { it('shows the "no environment" empty state', () => {
expect(findNoEnvironmentEmptyStates().length).toBe(2); expect(findNoEnvironmentEmptyState().exists()).toBe(true);
}); });
it('shows the tabs', () => { it('shows the tabs', () => {
expect(findPolicyTab().exists()).toBe(true); expect(findAlertTab().exists()).toBe(true);
expect(findStatisticsTab().exists()).toBe(true); expect(findStatisticsTab().exists()).toBe(true);
}); });
it('does not show the network policy list', () => {
expect(findPolicyList().exists()).toBe(false);
});
it('does not show the threat monitoring section', () => { it('does not show the threat monitoring section', () => {
expect(findPolicySection().exists()).toBe(false); expect(findStatisticsSection().exists()).toBe(false);
}); });
}, },
); );
...@@ -114,12 +107,8 @@ describe('ThreatMonitoringApp component', () => { ...@@ -114,12 +107,8 @@ describe('ThreatMonitoringApp component', () => {
expect(findFilters().exists()).toBe(true); expect(findFilters().exists()).toBe(true);
}); });
it('renders the network policy section', () => { it('renders the statistics section', () => {
expect(findPolicySection().element).toMatchSnapshot(); expect(findStatisticsSection().element).toMatchSnapshot();
});
it('renders the network policy tab', () => {
expect(findPolicyTab().element).toMatchSnapshot();
}); });
}); });
...@@ -134,14 +123,4 @@ describe('ThreatMonitoringApp component', () => { ...@@ -134,14 +123,4 @@ describe('ThreatMonitoringApp component', () => {
expect(findAlertsView().exists()).toBe(true); expect(findAlertsView().exists()).toBe(true);
}); });
}); });
describe('with "securityOrchestrationPoliciesConfiguration" feature flag enabled', () => {
beforeEach(() => {
factory({ provide: { glFeatures: { securityOrchestrationPoliciesConfiguration: true } } });
});
it('does not render the Policies tab', () => {
expect(findPolicyTab().exists()).toBe(false);
});
});
}); });
...@@ -57,11 +57,10 @@ describe('PolicyEditor component', () => { ...@@ -57,11 +57,10 @@ describe('PolicyEditor component', () => {
expect(findNeworkPolicyEditor().props('existingPolicy')).toBe(null); expect(findNeworkPolicyEditor().props('existingPolicy')).toBe(null);
}); });
it('renders the disabled form select', () => { it('renders the form select', () => {
const formSelect = findFormSelect(); const formSelect = findFormSelect();
expect(formSelect.exists()).toBe(true);
expect(formSelect.attributes('value')).toBe(POLICY_TYPE_COMPONENT_OPTIONS.container.value); expect(formSelect.attributes('value')).toBe(POLICY_TYPE_COMPONENT_OPTIONS.container.value);
expect(formSelect.attributes('disabled')).toBe('true'); expect(formSelect.attributes('disabled')).toBe(undefined);
}); });
it('shows an alert when "error" is emitted from the component', async () => { it('shows an alert when "error" is emitted from the component', async () => {
...@@ -111,16 +110,4 @@ describe('PolicyEditor component', () => { ...@@ -111,16 +110,4 @@ describe('PolicyEditor component', () => {
}, },
); );
}); });
describe('with "securityOrchestrationPoliciesConfiguration" feature flag enabled', () => {
beforeEach(() => {
factory({ provide: { glFeatures: { securityOrchestrationPoliciesConfiguration: true } } });
});
it('renders the form select', () => {
const formSelect = findFormSelect();
expect(formSelect.exists()).toBe(true);
expect(formSelect.attributes('disabled')).toBe(undefined);
});
});
}); });
import { GlTable, GlDrawer } from '@gitlab/ui';
import { createLocalVue } from '@vue/test-utils';
import { merge } from 'lodash';
import VueApollo from 'vue-apollo';
import { POLICY_TYPE_OPTIONS } from 'ee/threat_monitoring/components/constants';
import PolicyDrawer from 'ee/threat_monitoring/components/policy_drawer/policy_drawer.vue';
import PolicyList from 'ee/threat_monitoring/components/policy_list.vue';
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 createStore from 'ee/threat_monitoring/store';
import createMockApollo from 'helpers/mock_apollo_helper';
import { stubComponent } from 'helpers/stub_component';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { networkPolicies, scanExecutionPolicies } from '../mocks/mock_apollo';
import { mockNetworkPoliciesResponse, mockScanExecutionPoliciesResponse } from '../mocks/mock_data';
const localVue = createLocalVue();
localVue.use(VueApollo);
const fullPath = 'project/path';
const environments = [
{
id: 2,
global_id: 'gid://gitlab/Environment/2',
},
];
const defaultRequestHandlers = {
networkPolicies: networkPolicies(mockNetworkPoliciesResponse),
scanExecutionPolicies: scanExecutionPolicies(mockScanExecutionPoliciesResponse),
};
const pendingHandler = jest.fn(() => new Promise(() => {}));
describe('PolicyList component', () => {
let store;
let wrapper;
let requestHandlers;
const factory = (mountFn = mountExtended) => (options = {}) => {
store = createStore();
const { state, handlers, ...wrapperOptions } = options;
Object.assign(store.state.networkPolicies, {
...state,
});
store.state.threatMonitoring.environments = environments;
requestHandlers = {
...defaultRequestHandlers,
...handlers,
};
jest.spyOn(store, 'dispatch').mockImplementation(() => Promise.resolve());
wrapper = mountFn(
PolicyList,
merge(
{
propsData: {
documentationPath: 'documentation_path',
newPolicyPath: '/policies/new',
},
store,
provide: {
projectPath: fullPath,
},
apolloProvider: createMockApollo([
[networkPoliciesQuery, requestHandlers.networkPolicies],
[scanExecutionPoliciesQuery, requestHandlers.scanExecutionPolicies],
]),
stubs: {
PolicyDrawer: stubComponent(PolicyDrawer, {
props: {
...PolicyDrawer.props,
...GlDrawer.props,
},
}),
},
localVue,
},
wrapperOptions,
),
);
};
const mountShallowWrapper = factory(shallowMountExtended);
const mountWrapper = factory();
const findPolicyTypeFilter = () => wrapper.findByTestId('policy-type-filter');
const findEnvironmentsPicker = () => wrapper.find({ ref: 'environmentsPicker' });
const findPoliciesTable = () => wrapper.findComponent(GlTable);
const findPolicyStatusCells = () => wrapper.findAllByTestId('policy-status-cell');
const findPolicyDrawer = () => wrapper.findByTestId('policyDrawer');
const findAutodevopsAlert = () => wrapper.findByTestId('autodevopsAlert');
afterEach(() => {
wrapper.destroy();
});
describe('initial state', () => {
beforeEach(() => {
mountShallowWrapper({
handlers: {
networkPolicies: pendingHandler,
},
});
});
it('renders EnvironmentPicker', () => {
expect(findEnvironmentsPicker().exists()).toBe(true);
});
it('renders the new policy button', () => {
const button = wrapper.findByTestId('new-policy');
expect(button.exists()).toBe(true);
});
it('renders closed editor drawer', () => {
const editorDrawer = findPolicyDrawer();
expect(editorDrawer.exists()).toBe(true);
expect(editorDrawer.props('open')).toBe(false);
});
it('does not render autodevops alert', () => {
expect(findAutodevopsAlert().exists()).toBe(false);
});
it('fetches policies', () => {
expect(requestHandlers.networkPolicies).toHaveBeenCalledWith({
fullPath,
});
expect(requestHandlers.scanExecutionPolicies).toHaveBeenCalledWith({
fullPath,
});
});
it("sets table's loading state", () => {
expect(findPoliciesTable().attributes('busy')).toBe('true');
});
});
describe('given policies have been fetched', () => {
let rows;
beforeEach(async () => {
mountWrapper();
await waitForPromises();
rows = wrapper.findAll('tr');
});
it('fetches network policies on environment change', async () => {
store.dispatch.mockReset();
await store.commit('threatMonitoring/SET_CURRENT_ENVIRONMENT_ID', 2);
expect(requestHandlers.networkPolicies).toHaveBeenCalledTimes(2);
expect(requestHandlers.networkPolicies.mock.calls[1][0]).toEqual({
fullPath: 'project/path',
environmentId: environments[0].global_id,
});
});
it('if network policies are filtered out, changing the environment does not trigger a fetch', async () => {
store.dispatch.mockReset();
expect(requestHandlers.networkPolicies).toHaveBeenCalledTimes(1);
findPolicyTypeFilter().vm.$emit(
'input',
POLICY_TYPE_OPTIONS.POLICY_TYPE_SCAN_EXECUTION.value,
);
await store.commit('threatMonitoring/SET_CURRENT_ENVIRONMENT_ID', 2);
expect(requestHandlers.networkPolicies).toHaveBeenCalledTimes(1);
});
describe.each`
rowIndex | expectedPolicyName | expectedPolicyType
${1} | ${mockScanExecutionPoliciesResponse[0].name} | ${'Scan execution'}
${3} | ${mockNetworkPoliciesResponse[0].name} | ${'Network'}
${4} | ${'drop-outbound'} | ${'Network'}
${5} | ${'allow-inbound-http'} | ${'Network'}
`('policy in row #$rowIndex', ({ rowIndex, expectedPolicyName, expectedPolicyType }) => {
let row;
beforeEach(() => {
row = rows.at(rowIndex);
});
it(`renders ${expectedPolicyName} in the name cell`, () => {
expect(row.findAll('td').at(1).text()).toBe(expectedPolicyName);
});
it(`renders ${expectedPolicyType} in the policy type cell`, () => {
expect(row.findAll('td').at(2).text()).toBe(expectedPolicyType);
});
});
it.each`
description | filterBy | hiddenTypes
${'network'} | ${POLICY_TYPE_OPTIONS.POLICY_TYPE_NETWORK} | ${[POLICY_TYPE_OPTIONS.POLICY_TYPE_SCAN_EXECUTION]}
${'scan execution'} | ${POLICY_TYPE_OPTIONS.POLICY_TYPE_SCAN_EXECUTION} | ${[POLICY_TYPE_OPTIONS.POLICY_TYPE_NETWORK]}
`('policies filtered by $description type', async ({ filterBy, hiddenTypes }) => {
findPolicyTypeFilter().vm.$emit('input', filterBy.value);
await wrapper.vm.$nextTick();
expect(findPoliciesTable().text()).toContain(filterBy.text);
hiddenTypes.forEach((hiddenType) => {
expect(findPoliciesTable().text()).not.toContain(hiddenType.text);
});
});
});
describe('status column', () => {
beforeEach(() => {
mountWrapper();
});
it('renders a checkmark icon for enabled policies', () => {
const icon = findPolicyStatusCells().at(1).find('svg');
expect(icon.exists()).toBe(true);
expect(icon.props('name')).toBe('check-circle-filled');
expect(icon.props('ariaLabel')).toBe('Enabled');
});
it('renders a "Disabled" label for screen readers for disabled policies', () => {
const span = findPolicyStatusCells().at(3).find('span');
expect(span.exists()).toBe(true);
expect(span.attributes('class')).toBe('gl-sr-only');
expect(span.text()).toBe('Disabled');
});
});
describe('with allEnvironments enabled', () => {
beforeEach(() => {
mountWrapper();
wrapper.vm.$store.state.threatMonitoring.allEnvironments = true;
});
it('renders environments column', () => {
const environmentsHeader = findPoliciesTable().findAll('[role="columnheader"]').at(2);
expect(environmentsHeader.text()).toContain('Environment(s)');
});
});
describe.each`
description | policy
${'network'} | ${mockNetworkPoliciesResponse[0]}
${'scan execution'} | ${mockScanExecutionPoliciesResponse[0]}
`('given there is a $description policy selected', ({ policy }) => {
beforeEach(() => {
mountShallowWrapper();
findPoliciesTable().vm.$emit('row-selected', [policy]);
});
it('renders opened editor drawer', () => {
const editorDrawer = findPolicyDrawer();
expect(editorDrawer.exists()).toBe(true);
expect(editorDrawer.props('open')).toBe(true);
expect(editorDrawer.props('policy')).toBe(policy);
});
});
describe('given an autodevops policy', () => {
beforeEach(() => {
const autoDevOpsPolicy = {
...mockNetworkPoliciesResponse[0],
name: 'auto-devops',
fromAutoDevops: true,
};
mountShallowWrapper({
handlers: {
networkPolicies: networkPolicies([autoDevOpsPolicy]),
},
});
});
it('renders autodevops alert', () => {
expect(findAutodevopsAlert().exists()).toBe(true);
});
});
});
...@@ -22499,9 +22499,6 @@ msgstr "" ...@@ -22499,9 +22499,6 @@ msgstr ""
msgid "NetworkPolicies|IP/subnet" msgid "NetworkPolicies|IP/subnet"
msgstr "" msgstr ""
msgid "NetworkPolicies|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
msgstr ""
msgid "NetworkPolicies|Invalid or empty policy" msgid "NetworkPolicies|Invalid or empty policy"
msgstr "" msgstr ""
...@@ -22526,18 +22523,12 @@ msgstr "" ...@@ -22526,18 +22523,12 @@ msgstr ""
msgid "NetworkPolicies|New policy" msgid "NetworkPolicies|New policy"
msgstr "" msgstr ""
msgid "NetworkPolicies|No policies detected"
msgstr ""
msgid "NetworkPolicies|None selected" msgid "NetworkPolicies|None selected"
msgstr "" msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts." msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr "" msgstr ""
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
msgid "NetworkPolicies|Policy %{policyName} was successfully changed" msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
msgstr "" msgstr ""
...@@ -35078,9 +35069,6 @@ msgstr "" ...@@ -35078,9 +35069,6 @@ msgstr ""
msgid "ThreatMonitoring|Packet Activity" msgid "ThreatMonitoring|Packet Activity"
msgstr "" msgstr ""
msgid "ThreatMonitoring|Policies"
msgstr ""
msgid "ThreatMonitoring|Requests" msgid "ThreatMonitoring|Requests"
msgstr "" msgstr ""
......
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