Commit 8c7bf965 authored by Alexander Turinske's avatar Alexander Turinske

Abstract out policy editor data to helper

- add tests for new class
- create tests for UI
- add validation on injected paths
parent 51fa201b
...@@ -22,12 +22,13 @@ export default { ...@@ -22,12 +22,13 @@ export default {
GlLink, GlLink,
GlSprintf, GlSprintf,
}, },
inject: ['configureAgentHelpPath', 'createAgentHelpPath', 'projectPath'], inject: {
props: { configureAgentHelpPath: { type: String, default: '' },
policyAlert: { createAgentHelpPath: { type: String, default: '' },
type: Boolean, projectPath: { type: String, default: '' },
required: true,
}, },
props: {
policyAlert: { type: Boolean, required: true },
}, },
apollo: { apollo: {
isAgentInstalled: { isAgentInstalled: {
...@@ -52,10 +53,22 @@ export default { ...@@ -52,10 +53,22 @@ export default {
<template> <template>
<div> <div>
<gl-alert v-if="policyAlert" variant="warning" :dismissible="false" class="gl-mt-5"> <gl-alert
v-if="policyAlert"
variant="warning"
:dismissible="false"
class="gl-mt-5"
data-testid="policy-alert-high-volume"
>
{{ $options.i18n.HIGH_VOLUME_WARNING }} {{ $options.i18n.HIGH_VOLUME_WARNING }}
</gl-alert> </gl-alert>
<gl-alert v-if="!isAgentInstalled" variant="danger" :dismissible="false" class="gl-mt-5"> <gl-alert
v-if="!isAgentInstalled"
variant="danger"
:dismissible="false"
class="gl-mt-5"
data-testid="policy-alert-no-agent"
>
<gl-sprintf :message="$options.i18n.AGENT_REQUIRED"> <gl-sprintf :message="$options.i18n.AGENT_REQUIRED">
<template #installLink="{ content }"> <template #installLink="{ content }">
<gl-link :href="createAgentHelpPath" target="_blank"> <gl-link :href="createAgentHelpPath" target="_blank">
...@@ -88,7 +101,7 @@ export default { ...@@ -88,7 +101,7 @@ export default {
class="gl-w-full gl-display-flex gl-justify-content-space-between gl-align-items-center" class="gl-w-full gl-display-flex gl-justify-content-space-between gl-align-items-center"
> >
<span> <span>
<gl-sprintf :message="$options.i18n.ACTION"> <gl-sprintf :message="$options.i18n.ACTION" data-testid="policy-alert-message">
<template #label="{ content }"> <template #label="{ content }">
<label for="actionType" class="text-uppercase gl-font-lg gl-mr-4 gl-mb-0"> <label for="actionType" class="text-uppercase gl-font-lg gl-mr-4 gl-mb-0">
{{ content }} {{ content }}
......
# frozen_string_literal: true
module PolicyHelper
def policy_details(project, policy = nil, environment = nil)
return unless project
details = {
network_policies_endpoint: project_security_network_policies_path(project),
configure_agent_help_path: help_page_url('user/clusters/agent/repository.html'),
create_agent_help_path: help_page_url('user/clusters/agent/index.md', anchor: 'create-an-agent-record-in-gitlab'),
environments_endpoint: project_environments_path(project),
project_path: project.full_path,
threat_monitoring_path: project_threat_monitoring_path(project)
}
return details unless policy && environment
edit_details = {
policy: policy.to_json,
environment_id: environment.id
}
details.merge(edit_details)
end
end
- add_to_breadcrumbs s_("ThreatMonitoring|Threat Monitoring"), project_threat_monitoring_path(@project) - add_to_breadcrumbs s_("ThreatMonitoring|Threat Monitoring"), project_threat_monitoring_path(@project)
- breadcrumb_title @policy_name - breadcrumb_title @policy_name
- page_title s_("NetworkPolicies|Policy editor") - page_title s_("NetworkPolicies|Policy editor")
- policy_details = policy_details(@project, @policy, @environment)
#js-policy-builder-app{ data: { network_policies_endpoint: project_security_network_policies_path(@project), #js-policy-builder-app{ data: policy_details }
configure_agent_help_path: help_page_url('user/clusters/agent/repository.html'),
create_agent_help_path: help_page_url('user/clusters/agent/index.md', anchor: 'create-an-agent-record-in-gitlab'),
environments_endpoint: project_environments_path(@project),
threat_monitoring_path: project_threat_monitoring_path(@project),
policy: @policy.to_json,
project_path: @project.full_path,
environment_id: @environment.id,
} }
- add_to_breadcrumbs s_("ThreatMonitoring|Threat Monitoring"), project_threat_monitoring_path(@project) - add_to_breadcrumbs s_("ThreatMonitoring|Threat Monitoring"), project_threat_monitoring_path(@project)
- breadcrumb_title s_("NetworkPolicies|New policy") - breadcrumb_title s_("NetworkPolicies|New policy")
- page_title s_("NetworkPolicies|Policy editor") - page_title s_("NetworkPolicies|Policy editor")
- policy_details = policy_details(@project)
#js-policy-builder-app{ data: { network_policies_endpoint: project_security_network_policies_path(@project), #js-policy-builder-app{ data: policy_details }
configure_agent_help_path: help_page_url('user/clusters/agent/repository.html'),
create_agent_help_path: help_page_url('user/clusters/agent/index.md', anchor: 'create-an-agent-record-in-gitlab'),
environments_endpoint: project_environments_path(@project),
project_path: @project.full_path,
threat_monitoring_path: project_threat_monitoring_path(@project),
} }
import { shallowMount } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import { GlAlert, GlSprintf } from '@gitlab/ui'; import createMockApollo from 'helpers/mock_apollo_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import VueApollo from 'vue-apollo';
import PolicyAlertPicker from 'ee/threat_monitoring/components/policy_editor/policy_alert_picker.vue'; import PolicyAlertPicker from 'ee/threat_monitoring/components/policy_editor/policy_alert_picker.vue';
import getAgentCount from 'ee/threat_monitoring/graphql/queries/get_agent_count.query.graphql';
const localVue = createLocalVue();
localVue.use(VueApollo);
describe('PolicyAlertPicker component', () => { describe('PolicyAlertPicker component', () => {
let wrapper; let wrapper;
const createMockApolloProvider = ({ agentCount }) => {
const getAgentCountHandler = jest
.fn()
.mockResolvedValue({ data: { project: { clusterAgents: { count: agentCount } } } });
return createMockApollo([[getAgentCount, getAgentCountHandler]]);
};
const defaultProps = { policyAlert: false }; const defaultProps = { policyAlert: false };
const findAddAlertButton = () => wrapper.find("[data-testid='add-alert']"); const findAddAlertButton = () => wrapper.find("[data-testid='add-alert']");
const findGlAlert = () => wrapper.find(GlAlert); const findAlertMessage = () => wrapper.findByTestId('policy-alert-message');
const findGlSprintf = () => wrapper.find(GlSprintf); const findHighVolumeAlert = () => wrapper.findByTestId('policy-alert-high-volume');
const findNoAgentAlert = () => wrapper.findByTestId('policy-alert-no-agent');
const findRemoveAlertButton = () => wrapper.find("[data-testid='remove-alert']"); const findRemoveAlertButton = () => wrapper.find("[data-testid='remove-alert']");
const createWrapper = ({ propsData = defaultProps } = {}) => { const createWrapper = async ({ propsData = defaultProps, agentCount = 1 } = {}) => {
wrapper = shallowMount(PolicyAlertPicker, { const apolloProvider = createMockApolloProvider({ agentCount });
wrapper = extendedWrapper(
shallowMount(PolicyAlertPicker, {
apolloProvider,
localVue,
propsData: { propsData: {
...propsData, ...propsData,
}, },
}); provide: {
configureAgentHelpPath: '',
createAgentHelpPath: '',
projectPath: '',
},
}),
);
await wrapper.vm.$nextTick();
}; };
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null;
}); });
describe('default state', () => { describe('default state', () => {
beforeEach(() => { beforeEach(async () => {
createWrapper(); await createWrapper();
}); });
it('does render the add alert button', () => { it('does render the add alert button', () => {
...@@ -34,17 +62,21 @@ describe('PolicyAlertPicker component', () => { ...@@ -34,17 +62,21 @@ describe('PolicyAlertPicker component', () => {
}); });
it('does not render the high volume warning', () => { it('does not render the high volume warning', () => {
expect(findGlAlert().exists()).toBe(false); expect(findHighVolumeAlert().exists()).toBe(false);
}); });
it('does not render the alert message', () => { it('does not render the alert message', () => {
expect(findGlSprintf().exists()).toBe(false); expect(findAlertMessage().exists()).toBe(false);
}); });
it('does not render the remove alert button', () => { it('does not render the remove alert button', () => {
expect(findRemoveAlertButton().exists()).toBe(false); expect(findRemoveAlertButton().exists()).toBe(false);
}); });
it('does not show the "no agent" alert when there is an agent, ', () => {
expect(findNoAgentAlert().exists()).toBe(false);
});
it('does emit an event to add the alert', () => { it('does emit an event to add the alert', () => {
findAddAlertButton().vm.$emit('click'); findAddAlertButton().vm.$emit('click');
expect(wrapper.emitted('update-alert')).toEqual([[true]]); expect(wrapper.emitted('update-alert')).toEqual([[true]]);
...@@ -52,8 +84,8 @@ describe('PolicyAlertPicker component', () => { ...@@ -52,8 +84,8 @@ describe('PolicyAlertPicker component', () => {
}); });
describe('alert enabled', () => { describe('alert enabled', () => {
beforeEach(() => { beforeEach(async () => {
createWrapper({ propsData: { policyAlert: true } }); await createWrapper({ propsData: { policyAlert: true } });
}); });
it('does not render the add alert button', () => { it('does not render the add alert button', () => {
...@@ -61,20 +93,36 @@ describe('PolicyAlertPicker component', () => { ...@@ -61,20 +93,36 @@ describe('PolicyAlertPicker component', () => {
}); });
it('does render the high volume warning', () => { it('does render the high volume warning', () => {
expect(findGlAlert().exists()).toBe(true); expect(findHighVolumeAlert().exists()).toBe(true);
}); });
it('does render the alert message', () => { it('does render the alert message', () => {
expect(findGlSprintf().exists()).toBe(true); expect(findAlertMessage().exists()).toBe(true);
}); });
it('does render the remove alert button', () => { it('does render the remove alert button', () => {
expect(findRemoveAlertButton().exists()).toBe(true); expect(findRemoveAlertButton().exists()).toBe(true);
}); });
it('does not show the "no agent" alert when there is an agent, ', () => {
expect(findNoAgentAlert().exists()).toBe(false);
});
it('does emit an event to remove the alert', () => { it('does emit an event to remove the alert', () => {
findRemoveAlertButton().vm.$emit('click'); findRemoveAlertButton().vm.$emit('click');
expect(wrapper.emitted('update-alert')).toEqual([[false]]); expect(wrapper.emitted('update-alert')).toEqual([[false]]);
}); });
}); });
describe('no agent installed', () => {
it('add alert button is there and there is NOT an agent', async () => {
await createWrapper({ agentCount: 0 });
expect(findNoAgentAlert().exists()).toBe(true);
});
it('add alert button is NOT there and there is NOT an agent', async () => {
await createWrapper({ propsData: { policyAlert: true }, agentCount: 0 });
expect(findNoAgentAlert().exists()).toBe(true);
});
});
}); });
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe PolicyHelper do
let(:project) { create(:project, :repository, :public) }
let(:policy) do
Gitlab::Kubernetes::CiliumNetworkPolicy.new(
name: 'policy',
namespace: 'another',
selector: { matchLabels: { role: 'db' } },
ingress: [{ from: [{ namespaceSelector: { matchLabels: { project: 'myproject' } } }] }]
)
end
let(:environment) { create(:environment, project: project) }
describe '#policy_details' do
context 'when a new policy is being created' do
subject { helper.policy_details(project) }
it 'returns expected policy data' do
expect(subject).to match(
network_policies_endpoint: kind_of(String),
configure_agent_help_path: kind_of(String),
create_agent_help_path: kind_of(String),
environments_endpoint: kind_of(String),
project_path: project.full_path,
threat_monitoring_path: kind_of(String)
)
end
end
context 'when an existing policy is being edited' do
subject { helper.policy_details(project, policy, environment) }
it 'returns expected policy data' do
expect(subject).to match(
network_policies_endpoint: kind_of(String),
configure_agent_help_path: kind_of(String),
create_agent_help_path: kind_of(String),
environments_endpoint: kind_of(String),
project_path: project.full_path,
threat_monitoring_path: kind_of(String),
policy: policy.to_json,
environment_id: environment.id
)
end
end
end
end
...@@ -18845,6 +18845,9 @@ msgstr "" ...@@ -18845,6 +18845,9 @@ 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."
msgstr ""
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints." msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
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