Merge pull request #8815 from torchiaf/fix/8776-8774

[PolicyRuleTarget] add unit tests
This commit is contained in:
Francesco Torchia 2023-05-16 17:40:45 +02:00 committed by GitHub
commit abea5634f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 359 additions and 4 deletions

View File

@ -34,6 +34,10 @@ module.exports = {
'<rootDir>/stories/',
'<rootDir>/shell/scripts/',
],
testPathIgnorePatterns: [
'<rootDir>/node_modules/',
'<rootDir>(/.*)*/__tests__/utils/',
],
coverageDirectory: '<rootDir>/coverage/unit',
coverageReporters: ['json', 'text-summary'],
globals: { 'ts-jest': { isolatedModules: true } },

View File

@ -74,6 +74,7 @@ export default {
POD,
TARGET_OPTIONS,
targetOptions: Object.values(TARGET_OPTIONS),
throttleTime: 250,
};
},
computed: {
@ -139,7 +140,7 @@ export default {
handler: throttle(function() {
this.matchingNamespaces = this.getMatchingNamespaces();
this.matchingPods = this.getMatchingPods();
}, 250, { leading: true }),
}, this.throttle, { leading: true }),
immediate: true
};
},
@ -213,6 +214,7 @@ export default {
<div class="col span-6">
<LabeledSelect
v-model="targetType"
data-testid="labeled-select-type-selector"
:mode="mode"
:tooltip="targetType === TARGET_OPTIONS.NAMESPACE_AND_POD_SELECTOR ? t('networkpolicy.selectors.matchingNamespacesAndPods.tooltip') : null"
:options="selectTargetOptions"
@ -226,6 +228,7 @@ export default {
<div class="col span-6">
<LabeledInput
v-model="value[TARGET_OPTIONS.IP_BLOCK].cidr"
data-testid="labeled-input-ip-block-selector"
:mode="mode"
:placeholder="t('networkpolicy.rules.ipBlock.cidr.placeholder')"
:label="t('networkpolicy.rules.ipBlock.cidr.label')"
@ -277,6 +280,7 @@ export default {
<div class="col span-12">
<MatchExpressions
v-model="podSelectorExpressions"
data-testid="match-expression-pod-selector"
:mode="mode"
:show-remove="false"
:initial-empty-row="true"
@ -297,6 +301,7 @@ export default {
<div class="col span-12">
<MatchExpressions
v-model="namespaceSelectorExpressions"
data-testid="match-expression-namespace-selector"
:mode="mode"
:show-remove="false"
:initial-empty-row="true"
@ -329,6 +334,7 @@ export default {
<div class="col span-11">
<MatchExpressions
v-model="namespaceSelectorExpressions"
data-testid="match-expression-namespace-and-pod-selector-ns-rule"
:mode="mode"
:show-add-button="false"
:show-remove-button="false"
@ -347,6 +353,7 @@ export default {
<div class="col span-11">
<MatchExpressions
v-model="podSelectorExpressions"
data-testid="match-expression-namespace-and-pod-selector-pod-rule"
:mode="mode"
:show-add-button="false"
:show-remove-button="false"
@ -362,13 +369,14 @@ export default {
<style lang='scss' scoped>
.namespace-pod-rule {
display: table;
width: 100px;
margin: 0;
padding: 0, 10px, 0, 0;
text-align: center;
.label {
display: block;
margin-top: 32px;
display:table-cell;
vertical-align:middle;
}
}
</style>

View File

@ -0,0 +1,140 @@
import { mount } from '@vue/test-utils';
import PolicyRuleTarget from '@shell/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget';
import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
import mock from '@shell/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json';
import { PolicyRuleTargetSelectors } from '@shell/edit/networking.k8s.io.networkpolicy/__tests__/utils/selectors';
describe.each([
'view',
'edit',
])('component: PolicyRuleTarget', (mode) => {
const mockExists = jest.fn().mockReturnValue(true);
const mockT = jest.fn().mockReturnValue('some-string');
const wrapper = mount(PolicyRuleTarget, {
data() {
return { throttleTime: 0 };
},
propsData: {
namespace: mock.defaultNamespace,
allNamespaces: mock.allNamespaces,
allPods: mock.allPods,
type: 'ingress',
mode
},
directives: { cleanHtmlDirective },
mocks: {
$store: {
getters: {
'i18n/exists': mockExists,
'i18n/t': mockT
}
}
}
});
describe(`${ mode } mode`, () => {
it('should display ip-block selector rule', async() => {
const ipBlock = mock.selectors.ipBlock;
await wrapper.setProps({ value: { ipBlock } });
const selectors = new PolicyRuleTargetSelectors(wrapper);
// Check rule type selector
expect(selectors.ruleType.vm.$data._value.value).toBe('ipBlock');
expect(selectors.namespace.element).toBeUndefined();
expect(selectors.pod.element).toBeUndefined();
expect(selectors.namespaceAndPod.namespaceRule.element).toBeUndefined();
expect(selectors.namespaceAndPod.podRule.element).toBeUndefined();
expect(selectors.ipBlock.element._value).toStrictEqual(ipBlock.cidr);
});
it('should display namespace selector rule', async() => {
const namespaceSelector = mock.selectors.namespace;
await wrapper.setProps({ value: { namespaceSelector } });
const selectors = new PolicyRuleTargetSelectors(wrapper);
// Check rule type selector
expect(selectors.ruleType.vm.$data._value.value).toBe('namespaceSelector');
// Check the matching namespaces displayed by the banner
expect(wrapper.vm.$data.matchingNamespaces.matched).toBe(1);
// Check if namespace's labels match
expect(wrapper.vm.$data.matchingNamespaces.matches).toHaveLength(1);
expect(wrapper.vm.$data.matchingNamespaces.matches[0].metadata.name).toBe('default');
expect(wrapper.vm.$data.matchingNamespaces.matches[0].metadata.labels['user']).toBe('alice');
expect(selectors.pod.element).toBeUndefined();
expect(selectors.namespaceAndPod.namespaceRule.element).toBeUndefined();
expect(selectors.namespaceAndPod.podRule.element).toBeUndefined();
expect(selectors.namespace.element).toBeDefined();
});
it('should display pod selector rule', async() => {
const podSelector = mock.selectors.pod;
await wrapper.setProps({ value: { podSelector } });
const selectors = new PolicyRuleTargetSelectors(wrapper);
// Check rule type selector
expect(selectors.ruleType.vm.$data._value.value).toBe('podSelector');
// Check if namespace's labels match
expect(wrapper.vm.$data.matchingPods.matched).toBe(1);
expect(wrapper.vm.$data.matchingPods.matches).toHaveLength(1);
expect(wrapper.vm.$data.matchingPods.matches[0].metadata.name).toBe('test-pod');
expect(wrapper.vm.$data.matchingPods.matches[0].metadata.labels['foo']).toBe('bar');
expect(selectors.namespace.element).toBeUndefined();
expect(selectors.namespaceAndPod.namespaceRule.element).toBeUndefined();
expect(selectors.namespaceAndPod.podRule.element).toBeUndefined();
expect(selectors.pod.element).toBeDefined();
});
it('should display namespace/pod selector rule', async() => {
const namespaceSelector = mock.selectors.namespaceAndPod.namespace;
const podSelector = mock.selectors.namespaceAndPod.pod;
await wrapper.setProps({
value: {
namespaceSelector,
podSelector,
}
});
const selectors = new PolicyRuleTargetSelectors(wrapper);
// Check rule type selector
expect(selectors.ruleType.vm.$data._value.value).toBe('namespaceAndPodSelector');
// Check the matching pods displayed by the banner
expect(wrapper.vm.$data.matchingPods.matched).toBe(1);
// Check if namespace's labels match
expect(wrapper.vm.$data.matchingNamespaces.matches).toHaveLength(1);
expect(wrapper.vm.$data.matchingNamespaces.matches[0].metadata.name).toBe('default');
expect(wrapper.vm.$data.matchingNamespaces.matches[0].metadata.labels['user']).toBe('alice');
expect(wrapper.vm.$data.matchingPods.matches[0].metadata.name).toBe('test-pod');
expect(wrapper.vm.$data.matchingPods.matches[0].metadata.labels['foo']).toBe('bar');
expect(selectors.namespace.element).toBeUndefined();
expect(selectors.pod.element).toBeUndefined();
expect(selectors.namespaceAndPod.namespaceRule.element).toBeDefined();
expect(selectors.namespaceAndPod.podRule.element).toBeDefined();
});
});
});

View File

@ -0,0 +1,158 @@
{
"defaultNamespace": "default",
"selectors": {
"ipBlock": {
"cidr": "24.06.19.89/0"
},
"namespace": {
"matchLabels": {
"user": "alice"
},
"matchExpressions": [
{
"key": "user",
"operator": "In",
"values": "alice"
}
]
},
"pod": {
"matchLabels": {
"foo": "bar"
},
"matchExpressions": [
{
"key": "foo",
"operator": "In",
"values": "bar"
}
]
},
"namespaceAndPod": {
"namespace": {
"matchLabels": {
"user": "alice"
},
"matchExpressions": [
{
"key": "user",
"operator": "In",
"values": "alice"
}
]
},
"pod": {
"matchLabels": {
"foo": "bar"
},
"matchExpressions": [
{
"key": "foo",
"operator": "In",
"values": "bar"
}
]
}
}
},
"allNamespaces": [
{
"id": "default",
"type": "namespace",
"kind": "Namespace",
"metadata": {
"annotations": {
"user": "alice"
},
"name": "default",
"creationTimestamp": "2023-01-31T10:24:03Z",
"fields": ["default", "Active", "1d"],
"labels": {
"user": "alice"
},
"relationships": null,
"resourceVersion": "1",
"state": {
"error": false,
"message": "",
"name": "active",
"transitioning": false
}
},
"spec": { "finalizers": ["kubernetes"] },
"status": { "phase": "Active" }
},
{
"id": "not-default",
"type": "namespace",
"kind": "Namespace",
"metadata": {
"annotations": {
"user": "nicole"
},
"name": "not-default",
"creationTimestamp": "2023-01-31T10:24:03Z",
"fields": ["default", "Active", "1d"],
"labels": {
"user": "nicole"
},
"relationships": null,
"resourceVersion": "1",
"state": {
"error": false,
"message": "",
"name": "active",
"transitioning": false
}
},
"spec": { "finalizers": ["kubernetes"] },
"status": { "phase": "Active" }
}
],
"allPods": [
{
"id": "default/test-pod",
"type": "pod",
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"creationTimestamp": "2023-02-27T16:10:55Z",
"generateName": "test-pod-",
"labels": {
"foo": "bar"
},
"name": "test-pod",
"namespace": "default",
"resourceVersion": "1",
"state": {
"error": false,
"message": "",
"name": "completed",
"transitioning": false
}
}
},
{
"id": "default/test-pod-2",
"type": "pod",
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"creationTimestamp": "2023-02-27T16:10:55Z",
"generateName": "test-pod-2-",
"labels": {
"foo": "bar"
},
"name": "test-pod-2",
"namespace": "not-default",
"resourceVersion": "1",
"state": {
"error": false,
"message": "",
"name": "completed",
"transitioning": false
}
}
}
]
}

View File

@ -0,0 +1,45 @@
export class PolicyRuleTargetSelectors {
private wrapper;
constructor(wrapper: any) {
this.wrapper = wrapper;
}
get ipBlock() {
return this.wrapper.find('[data-testid=labeled-input-ip-block-selector]');
}
/**
* Namespace selector element; matches policies in OR condition, in conjunction with the other rules
*/
get namespace() {
return this.wrapper.find(
'[data-testid=match-expression-namespace-selector]'
);
}
/**
* Pod selector element; matches policies in OR condition, in conjunction with the other rules
*/
get pod() {
return this.wrapper.find('[data-testid=match-expression-pod-selector]');
}
/**
* Namespace and pod selector elements, matching policies in AND condition, within the same rule
*/
get namespaceAndPod() {
return {
namespaceRule: this.wrapper.find(
'[data-testid=match-expression-namespace-and-pod-selector-ns-rule]'
),
podRule: this.wrapper.find(
'[data-testid=match-expression-namespace-and-pod-selector-pod-rule]'
),
};
}
get ruleType() {
return this.wrapper.find('[data-testid=labeled-select-type-selector]');
}
}