Commit 21e8bf03 authored by Fernando Arias's avatar Fernando Arias Committed by Mark Florian

Implement AnalyzerConfiguration component

For SAST Configuration UI. Addresses
https://gitlab.com/gitlab-org/gitlab/-/issues/238600,
part of https://gitlab.com/groups/gitlab-org/-/epics/3635.
parent d08a9405
<script>
import { GlFormCheckbox } from '@gitlab/ui';
import { isValidAnalyzerEntity } from './utils';
export default {
components: {
GlFormCheckbox,
},
model: {
prop: 'entity',
event: 'input',
},
props: {
// SastCiConfigurationAnalyzersEntity from GraphQL endpoint
entity: {
type: Object,
required: true,
validator: isValidAnalyzerEntity,
},
},
methods: {
onToggle(value) {
const entity = { ...this.entity, enabled: value };
this.$emit('input', entity);
},
},
};
</script>
<template>
<gl-form-checkbox :id="entity.name" :checked="entity.enabled" @input="onToggle">
<span class="gl-font-weight-bold">{{ entity.label }}</span>
<span v-if="entity.description" class="gl-text-gray-500">({{ entity.description }})</span>
</gl-form-checkbox>
</template>
const isString = value => typeof value === 'string'; const isString = value => typeof value === 'string';
const isBoolean = value => typeof value === 'boolean';
export const isValidConfigurationEntity = object => { export const isValidConfigurationEntity = object => {
if (object == null) { if (object == null) {
...@@ -17,6 +18,16 @@ export const isValidConfigurationEntity = object => { ...@@ -17,6 +18,16 @@ export const isValidConfigurationEntity = object => {
); );
}; };
export const isValidAnalyzerEntity = object => {
if (object == null) {
return false;
}
const { name, label, description, enabled } = object;
return isString(name) && isString(label) && isString(description) && isBoolean(enabled);
};
export const extractSastConfigurationEntities = ({ project }) => { export const extractSastConfigurationEntities = ({ project }) => {
if (!project?.sastCiConfiguration) { if (!project?.sastCiConfiguration) {
return []; return [];
......
import { mount } from '@vue/test-utils';
import AnalyzerConfiguration from 'ee/security_configuration/sast/components/analyzer_configuration.vue';
describe('AnalyzerConfiguration component', () => {
let wrapper;
const entity = {
name: 'name',
label: 'label',
description: 'description',
enabled: false,
};
const createComponent = ({ props = {} } = {}) => {
wrapper = mount(AnalyzerConfiguration, {
propsData: {
...props,
},
});
};
const findInputElement = () => wrapper.find('input[type="checkbox"]');
afterEach(() => {
wrapper.destroy();
});
describe('label', () => {
beforeEach(() => {
createComponent({
props: { entity },
});
});
it('renders the label', () => {
expect(wrapper.text()).toContain(entity.label);
});
it('renders the description', () => {
expect(wrapper.text()).toContain(entity.description);
});
});
describe.each`
initiallyChecked
${false}
${true}
`('with checkbox initially checked $initiallyChecked ', ({ initiallyChecked }) => {
beforeEach(() => {
createComponent({
props: { entity: { ...entity, enabled: initiallyChecked } },
});
});
it('sets the checkbox input to the correct checked state', () => {
expect(findInputElement().element.checked).toBe(initiallyChecked);
});
describe('when the user checks the checkbox', () => {
beforeEach(() => {
findInputElement().setChecked(!initiallyChecked);
});
it('emits a input event with the checked value', () => {
expect(wrapper.emitted('input')).toEqual([[{ ...entity, enabled: !initiallyChecked }]]);
});
});
});
});
...@@ -17,3 +17,21 @@ export const makeEntities = (count, changes) => ...@@ -17,3 +17,21 @@ export const makeEntities = (count, changes) =>
value: `defaultValue${i}`, value: `defaultValue${i}`,
...changes, ...changes,
})); }));
/**
* Creates an array of objects matching the shape of a GraphQl
* SastCiConfigurationAnalyzersEntity.
*
* @param {number} count - The number of entities to create.
* @param {Object} [changes] - Object representing changes to apply to the
* generated entities.
* @returns {Object[]}
*/
export const makeAnalyzerEntities = (count, changes) =>
[...Array(count).keys()].map(i => ({
name: `nameValue${i}`,
label: `label${i}`,
description: `description${i}`,
enabled: true,
...changes,
}));
import { import {
isValidConfigurationEntity, isValidConfigurationEntity,
isValidAnalyzerEntity,
extractSastConfigurationEntities, extractSastConfigurationEntities,
} from 'ee/security_configuration/sast/components/utils'; } from 'ee/security_configuration/sast/components/utils';
import { makeEntities } from './helpers'; import { makeEntities, makeAnalyzerEntities } from './helpers';
describe('isValidConfigurationEntity', () => { describe('isValidConfigurationEntity', () => {
const validEntities = makeEntities(3); const validEntities = makeEntities(3);
...@@ -29,6 +30,30 @@ describe('isValidConfigurationEntity', () => { ...@@ -29,6 +30,30 @@ describe('isValidConfigurationEntity', () => {
}); });
}); });
describe('isValidAnalyzerEntity', () => {
const validEntities = makeAnalyzerEntities(3);
const invalidEntities = [
null,
undefined,
[],
{},
...makeAnalyzerEntities(1, { name: undefined }),
...makeAnalyzerEntities(1, { label: undefined }),
...makeAnalyzerEntities(1, { description: undefined }),
...makeAnalyzerEntities(1, { enabled: undefined }),
...makeAnalyzerEntities(1, { enabled: '' }),
];
it.each(validEntities)('returns true for a valid entity', entity => {
expect(isValidAnalyzerEntity(entity)).toBe(true);
});
it.each(invalidEntities)('returns false for an invalid entity', invalidEntity => {
expect(isValidAnalyzerEntity(invalidEntity)).toBe(false);
});
});
describe('extractSastConfigurationEntities', () => { describe('extractSastConfigurationEntities', () => {
describe.each` describe.each`
context | response context | response
......
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