Skip to content

Commit

Permalink
[ResponseOps][Cases] Add tags to template in configure api (#183743)
Browse files Browse the repository at this point in the history
## Summary

Parent issue: #181309

This PR adds optional tags field in template. 

### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
js-jankisalvi and kibanamachine committed May 21, 2024
1 parent 5eb9e81 commit b7fec99
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 43 deletions.
2 changes: 2 additions & 0 deletions x-pack/plugins/cases/common/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ export const MAX_TEMPLATE_KEY_LENGTH = 36 as const; // uuidv4 length
export const MAX_TEMPLATE_NAME_LENGTH = 50 as const;
export const MAX_TEMPLATE_DESCRIPTION_LENGTH = 1000 as const;
export const MAX_TEMPLATES_LENGTH = 10 as const;
export const MAX_TEMPLATE_TAG_LENGTH = 50 as const;
export const MAX_TAGS_PER_TEMPLATE = 10 as const;

/**
* Cases features
Expand Down
31 changes: 31 additions & 0 deletions x-pack/plugins/cases/common/types/api/configure/v1.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ import {
MAX_DESCRIPTION_LENGTH,
MAX_LENGTH_PER_TAG,
MAX_TAGS_PER_CASE,
MAX_TAGS_PER_TEMPLATE,
MAX_TEMPLATES_LENGTH,
MAX_TEMPLATE_DESCRIPTION_LENGTH,
MAX_TEMPLATE_KEY_LENGTH,
MAX_TEMPLATE_NAME_LENGTH,
MAX_TEMPLATE_TAG_LENGTH,
MAX_TITLE_LENGTH,
} from '../../../constants';
import { CaseSeverity } from '../../domain';
Expand Down Expand Up @@ -110,6 +112,7 @@ describe('configure', () => {
key: 'template_key_1',
name: 'Template 1',
description: 'this is first template',
tags: ['foo', 'bar'],
caseFields: {
title: 'case using sample template',
},
Expand All @@ -118,6 +121,7 @@ describe('configure', () => {
key: 'template_key_2',
name: 'Template 2',
description: 'this is second template',
tags: [],
caseFields: null,
},
],
Expand Down Expand Up @@ -222,6 +226,7 @@ describe('configure', () => {
key: 'template_key_1',
name: 'Template 1',
description: 'this is first template',
tags: ['foo', 'bar'],
caseFields: {
title: 'case using sample template',
},
Expand All @@ -247,6 +252,7 @@ describe('configure', () => {
key: 'template_key_1',
name: 'Template 1',
description: 'this is first template',
tags: [],
caseFields: {
title: 'case using sample template',
},
Expand Down Expand Up @@ -511,6 +517,7 @@ describe('configure', () => {
key: 'template_key_1',
name: 'Template 1',
description: 'this is first template',
tags: ['foo', 'bar'],
caseFields: {
title: 'case using sample template',
},
Expand Down Expand Up @@ -596,6 +603,30 @@ describe('configure', () => {
).toContain('The length of the description is too long. The maximum length is 1000.');
});

it(`throws an error when there are more than ${MAX_TAGS_PER_TEMPLATE} tags`, async () => {
const tags = Array(MAX_TAGS_PER_TEMPLATE + 1).fill('foobar');

expect(
PathReporter.report(TemplateConfigurationRt.decode({ ...defaultRequest, tags }))
).toContain(
`The length of the field template's tags is too long. Array must be of length <= 10.`
);
});

it(`throws an error when the a tag is more than ${MAX_TEMPLATE_TAG_LENGTH} characters`, async () => {
const tag = 'a'.repeat(MAX_TEMPLATE_TAG_LENGTH + 1);

expect(
PathReporter.report(TemplateConfigurationRt.decode({ ...defaultRequest, tags: [tag] }))
).toContain(`The length of the template's tag is too long. The maximum length is 50.`);
});

it(`throws an error when the a tag is empty string`, async () => {
expect(
PathReporter.report(TemplateConfigurationRt.decode({ ...defaultRequest, tags: [''] }))
).toContain(`The template's tag field cannot be an empty string.`);
});

describe('caseFields', () => {
it('removes foo:bar attributes from caseFields', () => {
const query = TemplateConfigurationRt.decode({
Expand Down
71 changes: 46 additions & 25 deletions x-pack/plugins/cases/common/types/api/configure/v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import {
MAX_CUSTOM_FIELDS_PER_CASE,
MAX_CUSTOM_FIELD_KEY_LENGTH,
MAX_CUSTOM_FIELD_LABEL_LENGTH,
MAX_TAGS_PER_TEMPLATE,
MAX_TEMPLATES_LENGTH,
MAX_TEMPLATE_DESCRIPTION_LENGTH,
MAX_TEMPLATE_KEY_LENGTH,
MAX_TEMPLATE_NAME_LENGTH,
MAX_TEMPLATE_TAG_LENGTH,
} from '../../../constants';
import { limitedArraySchema, limitedStringSchema, regexStringRt } from '../../../schema';
import { CustomFieldTextTypeRt, CustomFieldToggleTypeRt } from '../../domain';
Expand Down Expand Up @@ -69,32 +71,51 @@ export const CustomFieldsConfigurationRt = limitedArraySchema({
fieldName: 'customFields',
});

export const TemplateConfigurationRt = rt.strict({
/**
* key of template
*/
key: regexStringRt({
codec: limitedStringSchema({ fieldName: 'key', min: 1, max: MAX_TEMPLATE_KEY_LENGTH }),
pattern: '^[a-z0-9_-]+$',
message: `Key must be lower case, a-z, 0-9, '_', and '-' are allowed`,
}),
/**
* name of template
*/
name: limitedStringSchema({ fieldName: 'name', min: 1, max: MAX_TEMPLATE_NAME_LENGTH }),
/**
* description of templates
*/
description: limitedStringSchema({
fieldName: 'description',
min: 1,
max: MAX_TEMPLATE_DESCRIPTION_LENGTH,
export const TemplateConfigurationRt = rt.intersection([
rt.strict({
/**
* key of template
*/
key: regexStringRt({
codec: limitedStringSchema({ fieldName: 'key', min: 1, max: MAX_TEMPLATE_KEY_LENGTH }),
pattern: '^[a-z0-9_-]+$',
message: `Key must be lower case, a-z, 0-9, '_', and '-' are allowed`,
}),
/**
* name of template
*/
name: limitedStringSchema({ fieldName: 'name', min: 1, max: MAX_TEMPLATE_NAME_LENGTH }),
/**
* description of templates
*/
description: limitedStringSchema({
fieldName: 'description',
min: 1,
max: MAX_TEMPLATE_DESCRIPTION_LENGTH,
}),
/**
* case fields
*/
caseFields: rt.union([rt.null, CaseBaseOptionalFieldsRequestRt]),
}),
/**
* case fields
*/
caseFields: rt.union([rt.null, CaseBaseOptionalFieldsRequestRt]),
});
rt.exact(
rt.partial({
/**
* tags of templates
*/
tags: limitedArraySchema({
codec: limitedStringSchema({
fieldName: `template's tag`,
min: 1,
max: MAX_TEMPLATE_TAG_LENGTH,
}),
min: 0,
max: MAX_TAGS_PER_TEMPLATE,
fieldName: `template's tags`,
}),
})
),
]);

export const TemplatesConfigurationRt = limitedArraySchema({
codec: TemplateConfigurationRt,
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/cases/common/types/domain/configure/v1.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ describe('configure', () => {
key: 'template_sample_1',
name: 'Sample template 1',
description: 'this is first sample template',
tags: ['foo', 'bar', 'foobar'],
caseFields: {
title: 'Case with sample template 1',
description: 'case desc',
Expand Down Expand Up @@ -81,6 +82,7 @@ describe('configure', () => {
key: 'template_sample_2',
name: 'Sample template 2',
description: 'this is second sample template',
tags: [],
caseFields: {
title: 'Case with sample template 2',
tags: ['sample-2'],
Expand Down
46 changes: 28 additions & 18 deletions x-pack/plugins/cases/common/types/domain/configure/v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,34 @@ export const CustomFieldConfigurationRt = rt.union([

export const CustomFieldsConfigurationRt = rt.array(CustomFieldConfigurationRt);

export const TemplateConfigurationRt = rt.strict({
/**
* key of template
*/
key: rt.string,
/**
* name of template
*/
name: rt.string,
/**
* description of template
*/
description: rt.string,
/**
* case fields of template
*/
caseFields: rt.union([rt.null, CaseBaseOptionalFieldsRt]),
});
export const TemplateConfigurationRt = rt.intersection([
rt.strict({
/**
* key of template
*/
key: rt.string,
/**
* name of template
*/
name: rt.string,
/**
* description of template
*/
description: rt.string,
/**
* case fields of template
*/
caseFields: rt.union([rt.null, CaseBaseOptionalFieldsRt]),
}),
rt.exact(
rt.partial({
/**
* tags of template
*/
tags: rt.array(rt.string),
})
),
]);

export const TemplatesConfigurationRt = rt.array(TemplateConfigurationRt);

Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/cases/public/containers/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1190,12 +1190,14 @@ export const templatesConfigurationMock: CasesConfigurationUITemplate[] = [
key: 'test_template_2',
name: 'Second test template',
description: 'This is a second test template',
tags: [],
caseFields: {},
},
{
key: 'test_template_3',
name: 'Third test template',
description: 'This is a third test template with few case fields',
tags: ['foo'],
caseFields: {
title: 'This is case title using a test template',
severity: CaseSeverity.MEDIUM,
Expand All @@ -1206,6 +1208,7 @@ export const templatesConfigurationMock: CasesConfigurationUITemplate[] = [
key: 'test_template_4',
name: 'Fourth test template',
description: 'This is a fourth test template',
tags: ['foo', 'bar'],
caseFields: {
title: 'Case with sample template 4',
description: 'case desc',
Expand Down
12 changes: 12 additions & 0 deletions x-pack/plugins/cases/server/client/configure/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ describe('client', () => {
key: 'template_1',
name: 'template 1',
description: 'test',
tags: ['foo', 'bar'],
caseFields: {
title: 'Case title',
description: 'This is test desc',
Expand Down Expand Up @@ -415,6 +416,7 @@ describe('client', () => {
key: 'template_1',
name: 'template 1',
description: 'test',
tags: ['foo', 'bar'],
caseFields: {
title: 'Case title',
description: 'This is test desc',
Expand Down Expand Up @@ -450,6 +452,7 @@ describe('client', () => {
key: 'template_1',
name: 'template 1',
description: 'test',
tags: ['foo', 'bar'],
caseFields: {
title: 'Case title',
description: 'This is test desc',
Expand Down Expand Up @@ -532,12 +535,14 @@ describe('client', () => {
key: 'template_1',
name: 'template 1',
description: 'test',
tags: ['foo', 'bar'],
caseFields: null,
},
{
key: 'template_1',
name: 'template 2',
description: 'test',
tags: [],
caseFields: {
title: 'Case title',
},
Expand Down Expand Up @@ -798,6 +803,7 @@ describe('client', () => {
key: 'template_1',
name: 'template 1',
description: 'this is test description',
tags: ['foo', 'bar'],
caseFields: null,
},
],
Expand All @@ -814,6 +820,7 @@ describe('client', () => {
key: 'template_1',
name: 'template 1',
description: 'this is test description',
tags: ['foo', 'bar'],
caseFields: {
assignees: [{ uid: '1' }],
},
Expand Down Expand Up @@ -928,6 +935,7 @@ describe('client', () => {
key: 'duplicated_key',
name: 'template 2',
description: 'test',
tags: [],
caseFields: {
title: 'Case title',
},
Expand Down Expand Up @@ -957,6 +965,7 @@ describe('client', () => {
key: 'template_1',
name: 'template 1',
description: 'test',
tags: ['foo', 'bar'],
caseFields: {
customFields: [
{
Expand Down Expand Up @@ -1043,6 +1052,7 @@ describe('client', () => {
key: 'template_1',
name: 'template 1',
description: 'this is test description',
tags: ['foo', 'bar'],
caseFields: {
customFields: [
{
Expand Down Expand Up @@ -1081,6 +1091,7 @@ describe('client', () => {
key: 'template_1',
name: 'template 1',
description: 'test',
tags: ['foo', 'bar'],
caseFields: {
customFields: [
{
Expand Down Expand Up @@ -1196,6 +1207,7 @@ describe('client', () => {
key: 'template_1',
name: 'template 1',
description: 'this is test description',
tags: [],
caseFields: {
assignees: [{ uid: '1' }],
},
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/cases/server/common/types/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type PersistedTemplatesConfiguration = Array<{
key: string;
name: string;
description: string;
tags?: string[];
caseFields?: CaseFieldsAttributes | null;
}>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,14 @@ export default ({ getService }: FtrProviderContext): void => {
key: 'test_template_1',
name: 'First test template',
description: 'This is a first test template',
tags: [],
caseFields: null,
},
{
key: 'test_template_2',
name: 'Second test template',
description: 'This is a second test template',
tags: ['foobar'],
caseFields: {
title: 'Case with sample template 2',
description: 'case desc',
Expand Down
Loading

0 comments on commit b7fec99

Please sign in to comment.