[8.6] [Security Solution] [Exceptions] Fix edit the exception while adding new comment. (#145575) (#145724)

# Backport

This will backport the following commits from `main` to `8.6`:
- [[Security Solution] [Exceptions] Fix edit the exception while adding
new comment. (#145575)](https://github.com/elastic/kibana/pull/145575)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Wafaa
Nasr","email":"wafaa.nasr@elastic.co"},"sourceCommit":{"committedDate":"2022-11-18T13:35:03Z","message":"[Security
Solution] [Exceptions] Fix edit the exception while adding new comment.
(#145575)\n\n## Summary\r\n\r\nAddress
https://github.com/elastic/kibana/issues/144523\r\n\r\n1. Fix type
schema check to use `updateExceptionListItemSchema` instead\r\nof
`exceptionListItemSchema` as the comments array could be empty
when\r\nthe user adds the Exceptions and in Editing with adding a new
comment(s)\r\nit will contain only (comment and id) in the newly created
comment\r\n\r\n2. Add `removeCreatedAtCreatedByFromCommentsOnUpdate` to
remove the\r\n`createdAt`, and `createdBy` from the updated exception
Item if a\r\ncomment was added before to fix the `400 Schema
validations` as per the\r\nbelow
Schema\r\n\r\nThe\r\n`packages/kbn-securitysolution-io-ts-list-types/src/common/update_comment/index.ts`\r\n
\r\n ```\r\n export const updateComment = t.intersection([\r\n
t.exact(\r\n t.type({\r\n comment: NonEmptyString,\r\n })\r\n ),\r\n
t.exact(\r\n t.partial({\r\n id,\r\n })\r\n ),\r\n ]);\r\n ```\r\n3.
Moving tests and mocks to the `hooks` package as well add new
tests\r\nfor the new
`removeCreatedAtCreatedByFromCommentsOnUpdate`\r\n\r\n###
Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\nCo-authored-by: Kibana Machine
<42973632+kibanamachine@users.noreply.github.com>","sha":"2bd2226cb259312b90ad32b1cd5618a0cc2e8b49","branchLabelMapping":{"^v8.7.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:
SecuritySolution","Team:Security Solution
Platform","v8.6.0","v8.7.0"],"number":145575,"url":"https://github.com/elastic/kibana/pull/145575","mergeCommit":{"message":"[Security
Solution] [Exceptions] Fix edit the exception while adding new comment.
(#145575)\n\n## Summary\r\n\r\nAddress
https://github.com/elastic/kibana/issues/144523\r\n\r\n1. Fix type
schema check to use `updateExceptionListItemSchema` instead\r\nof
`exceptionListItemSchema` as the comments array could be empty
when\r\nthe user adds the Exceptions and in Editing with adding a new
comment(s)\r\nit will contain only (comment and id) in the newly created
comment\r\n\r\n2. Add `removeCreatedAtCreatedByFromCommentsOnUpdate` to
remove the\r\n`createdAt`, and `createdBy` from the updated exception
Item if a\r\ncomment was added before to fix the `400 Schema
validations` as per the\r\nbelow
Schema\r\n\r\nThe\r\n`packages/kbn-securitysolution-io-ts-list-types/src/common/update_comment/index.ts`\r\n
\r\n ```\r\n export const updateComment = t.intersection([\r\n
t.exact(\r\n t.type({\r\n comment: NonEmptyString,\r\n })\r\n ),\r\n
t.exact(\r\n t.partial({\r\n id,\r\n })\r\n ),\r\n ]);\r\n ```\r\n3.
Moving tests and mocks to the `hooks` package as well add new
tests\r\nfor the new
`removeCreatedAtCreatedByFromCommentsOnUpdate`\r\n\r\n###
Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\nCo-authored-by: Kibana Machine
<42973632+kibanamachine@users.noreply.github.com>","sha":"2bd2226cb259312b90ad32b1cd5618a0cc2e8b49"}},"sourceBranch":"main","suggestedTargetBranches":["8.6"],"targetPullRequestStates":[{"branch":"8.6","label":"v8.6.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.7.0","labelRegex":"^v8.7.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/145575","number":145575,"mergeCommit":{"message":"[Security
Solution] [Exceptions] Fix edit the exception while adding new comment.
(#145575)\n\n## Summary\r\n\r\nAddress
https://github.com/elastic/kibana/issues/144523\r\n\r\n1. Fix type
schema check to use `updateExceptionListItemSchema` instead\r\nof
`exceptionListItemSchema` as the comments array could be empty
when\r\nthe user adds the Exceptions and in Editing with adding a new
comment(s)\r\nit will contain only (comment and id) in the newly created
comment\r\n\r\n2. Add `removeCreatedAtCreatedByFromCommentsOnUpdate` to
remove the\r\n`createdAt`, and `createdBy` from the updated exception
Item if a\r\ncomment was added before to fix the `400 Schema
validations` as per the\r\nbelow
Schema\r\n\r\nThe\r\n`packages/kbn-securitysolution-io-ts-list-types/src/common/update_comment/index.ts`\r\n
\r\n ```\r\n export const updateComment = t.intersection([\r\n
t.exact(\r\n t.type({\r\n comment: NonEmptyString,\r\n })\r\n ),\r\n
t.exact(\r\n t.partial({\r\n id,\r\n })\r\n ),\r\n ]);\r\n ```\r\n3.
Moving tests and mocks to the `hooks` package as well add new
tests\r\nfor the new
`removeCreatedAtCreatedByFromCommentsOnUpdate`\r\n\r\n###
Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\nCo-authored-by: Kibana Machine
<42973632+kibanamachine@users.noreply.github.com>","sha":"2bd2226cb259312b90ad32b1cd5618a0cc2e8b49"}}]}]
BACKPORT-->

Co-authored-by: Wafaa Nasr <wafaa.nasr@elastic.co>
This commit is contained in:
Kibana Machine 2022-11-18 10:11:25 -05:00 committed by GitHub
parent 4f85f53671
commit 68bd9a95e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 577 additions and 6 deletions

View file

@ -5,6 +5,15 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import {
CommentsArray,
EntriesArray,
Entry,
EntryMatch,
EntryNested,
OsTypeArray,
} from '@kbn/securitysolution-io-ts-list-types';
export const DATE_NOW = '2020-04-20T15:25:31.830Z';
export const USER = 'some user';
export const ELASTIC_USER = 'elastic';
@ -18,3 +27,73 @@ export const TYPE = 'ip';
export const VERSION = 1;
export const IMMUTABLE = false;
// Exception List specific
export const ID = 'uuid_here';
export const NAMESPACE_TYPE = 'single';
export const OS_TYPES: OsTypeArray = ['windows'];
export const TAGS = [];
export const UPDATED_COMMENTS = [
{
comment: 'old comment',
id: 'old_created_id',
},
{
comment: 'new comment',
id: 'new_id',
},
];
export const COMMENTS = [];
export const ENTRIES: EntriesArray = [
{
entries: [{ field: 'nested.field', operator: 'included', type: 'match', value: 'some value' }],
field: 'some.parentField',
type: 'nested',
},
{ field: 'some.not.nested.field', operator: 'included', type: 'match', value: 'some value' },
];
export const ITEM_ID = 'some-list-item-id';
export const ITEM_TYPE = 'simple';
export const LIST_ITEM_ID = 'some-list-item-id';
// ENTRIES_WITH_IDS should only be used to mock out functionality of a collection of transforms
// that are UI specific and useful for UI concerns that are inserted between the
// API and the actual user interface. In some ways these might be viewed as
// technical debt or to compensate for the differences and preferences
// of how ReactJS might prefer data vs. how we want to model data.
export const ENTRIES_WITH_IDS: EntriesArray = [
{
entries: [
{
field: 'nested.field',
id: '123',
operator: 'included',
type: 'match',
value: 'some value',
} as EntryMatch & { id: string },
],
field: 'some.parentField',
id: '123',
type: 'nested',
} as EntryNested & { id: string },
{
field: 'some.not.nested.field',
id: '123',
operator: 'included',
type: 'match',
value: 'some value',
} as Entry & { id: string },
];
export const COMMENTS_WITH_CREATEDAT_CREATEDBY: CommentsArray = [
{
comment: 'old comment',
id: 'old_created_id',
created_at: '2022-01-08T15:25:31.830Z',
created_by: 'elastic',
},
{
comment: 'new comment',
id: 'new_id',
created_at: '2022-05-14T15:25:31.830Z',
created_by: 'elastic',
},
];

View file

@ -0,0 +1,63 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import type { CreateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types';
import {
COMMENTS,
DESCRIPTION,
ENTRIES,
ITEM_ID,
ITEM_TYPE,
LIST_ID,
META,
NAME,
NAMESPACE_TYPE,
OS_TYPES,
TAGS,
} from '../constants.mock';
export const getCreateExceptionListItemSchemaMock = (): CreateExceptionListItemSchema => ({
comments: COMMENTS,
description: DESCRIPTION,
entries: ENTRIES,
item_id: undefined,
list_id: LIST_ID,
meta: META,
name: NAME,
namespace_type: NAMESPACE_TYPE,
os_types: OS_TYPES,
tags: TAGS,
type: ITEM_TYPE,
});
/**
* Useful for end to end testing
*/
export const getCreateExceptionListItemMinimalSchemaMock = (): CreateExceptionListItemSchema => ({
description: DESCRIPTION,
entries: ENTRIES,
item_id: ITEM_ID,
list_id: LIST_ID,
name: NAME,
os_types: OS_TYPES,
type: ITEM_TYPE,
});
/**
* Useful for end to end testing
*/
export const getCreateExceptionListItemMinimalSchemaMockWithoutId =
(): CreateExceptionListItemSchema => ({
description: DESCRIPTION,
entries: ENTRIES,
list_id: LIST_ID,
name: NAME,
os_types: OS_TYPES,
type: ITEM_TYPE,
});

View file

@ -0,0 +1,52 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import type { UpdateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types';
import {
DESCRIPTION,
ENTRIES,
ID,
ITEM_ID,
ITEM_TYPE,
LIST_ITEM_ID,
META,
NAME,
NAMESPACE_TYPE,
OS_TYPES,
TAGS,
UPDATED_COMMENTS,
} from '../constants.mock';
export const getUpdateExceptionListItemSchemaMock = (): UpdateExceptionListItemSchema => ({
_version: undefined,
comments: UPDATED_COMMENTS,
description: DESCRIPTION,
entries: ENTRIES,
id: ID,
item_id: LIST_ITEM_ID,
meta: META,
name: NAME,
namespace_type: NAMESPACE_TYPE,
os_types: ['linux'],
tags: TAGS,
type: ITEM_TYPE,
});
/**
* Useful for end to end tests and other mechanisms which want to fill in the values
* after doing a get of the structure.
*/
export const getUpdateMinimalExceptionListItemSchemaMock = (): UpdateExceptionListItemSchema => ({
description: DESCRIPTION,
entries: ENTRIES,
item_id: ITEM_ID,
name: NAME,
os_types: OS_TYPES,
type: ITEM_TYPE,
});

View file

@ -0,0 +1,70 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types';
import {
COMMENTS,
DATE_NOW,
DESCRIPTION,
ELASTIC_USER,
ENTRIES,
ITEM_ID,
ITEM_TYPE,
LIST_ID,
META,
NAME,
NAMESPACE_TYPE,
OS_TYPES,
TIE_BREAKER,
USER,
} from '../constants.mock';
export const getExceptionListItemSchemaMock = (
overrides?: Partial<ExceptionListItemSchema>
): ExceptionListItemSchema => ({
_version: undefined,
comments: COMMENTS,
created_at: DATE_NOW,
created_by: USER,
description: DESCRIPTION,
entries: ENTRIES,
id: '1',
item_id: 'endpoint_list_item',
list_id: 'endpoint_list_id',
meta: META,
name: NAME,
namespace_type: NAMESPACE_TYPE,
os_types: [],
tags: ['user added string for a tag', 'malware'],
tie_breaker_id: TIE_BREAKER,
type: ITEM_TYPE,
updated_at: DATE_NOW,
updated_by: USER,
...(overrides || {}),
});
/**
* This is useful for end to end tests where we remove the auto generated parts for comparisons
* such as created_at, updated_at, and id.
*/
export const getExceptionListItemResponseMockWithoutAutoGeneratedValues =
(): Partial<ExceptionListItemSchema> => ({
comments: [],
created_by: ELASTIC_USER,
description: DESCRIPTION,
entries: ENTRIES,
item_id: ITEM_ID,
list_id: LIST_ID,
name: NAME,
namespace_type: 'single',
os_types: OS_TYPES,
tags: [],
type: ITEM_TYPE,
updated_by: ELASTIC_USER,
});

View file

@ -6,9 +6,293 @@
* Side Public License, v 1.
*/
import type {
CreateExceptionListItemSchema,
Entry,
EntryMatch,
EntryNested,
ExceptionListItemSchema,
UpdateExceptionListItemSchema,
} from '@kbn/securitysolution-io-ts-list-types';
import {
addIdToExceptionItemEntries,
removeIdFromExceptionItemsEntries,
transformInput,
transformOutput,
} from '@kbn/securitysolution-list-hooks';
import { getCreateExceptionListItemSchemaMock } from '../mocks/request/create_exception_list_item_schema.mock';
import { getUpdateExceptionListItemSchemaMock } from '../mocks/request/update_exception_list_item_schema.mock';
import { getExceptionListItemSchemaMock } from '../mocks/response/exception_list_item_schema.mock';
import { COMMENTS_WITH_CREATEDAT_CREATEDBY, ENTRIES_WITH_IDS } from '../mocks/constants.mock';
jest.mock('uuid', () => ({
v4: jest.fn().mockReturnValue('123'),
}));
describe('Exceptions transforms', () => {
test('Tests should be ported', () => {
// TODO: Port all the tests from: x-pack/plugins/lists/public/exceptions/transforms.test.ts here once mocks are figured out and kbn package mocks are figured out
expect(true).toBe(true);
describe('transformOutput', () => {
it('should return same output as input with stripped ids per entry - CreateExceptionListItemSchema', () => {
const mockCreateExceptionItem = {
...getCreateExceptionListItemSchemaMock(),
entries: ENTRIES_WITH_IDS,
};
const output = transformOutput(mockCreateExceptionItem);
const expectedOutput: CreateExceptionListItemSchema = getCreateExceptionListItemSchemaMock();
expect(output).toEqual(expectedOutput);
});
it('should return same output as input with stripped ids per entry - UpdateExceptionListItemSchema', () => {
const mockUpdateExceptionItem = {
...getUpdateExceptionListItemSchemaMock(),
entries: ENTRIES_WITH_IDS,
};
const output = transformOutput(mockUpdateExceptionItem);
const expectedOutput: UpdateExceptionListItemSchema = getUpdateExceptionListItemSchemaMock();
expect(output).toEqual(expectedOutput);
});
it('should return output as input with stripped createdAt and createdBy per entry - UpdateExceptionListItemSchema', () => {
const mockUpdateExceptionItem = {
...getUpdateExceptionListItemSchemaMock(),
entries: ENTRIES_WITH_IDS,
comments: COMMENTS_WITH_CREATEDAT_CREATEDBY,
};
const output = transformOutput(mockUpdateExceptionItem);
const expectedOutput: UpdateExceptionListItemSchema = getUpdateExceptionListItemSchemaMock();
expect(output).toEqual(expectedOutput);
});
});
describe('transformInput', () => {
it('should return same output as input with added ids per entry', () => {
const mockExceptionItem = getExceptionListItemSchemaMock();
const output = transformInput(mockExceptionItem);
const expectedOutput: ExceptionListItemSchema = {
...getExceptionListItemSchemaMock(),
entries: ENTRIES_WITH_IDS,
};
expect(output).toEqual(expectedOutput);
});
});
describe('addIdToExceptionItemEntries', () => {
it('should return same output as input with added ids per entry', () => {
const mockExceptionItem: ExceptionListItemSchema = {
...getExceptionListItemSchemaMock(),
entries: [
{
field: 'some.not.nested.field',
operator: 'included',
type: 'match',
value: 'some value',
},
],
};
const output = addIdToExceptionItemEntries(mockExceptionItem);
const expectedOutput: ExceptionListItemSchema = {
...getExceptionListItemSchemaMock(),
entries: [
{
field: 'some.not.nested.field',
id: '123',
operator: 'included',
type: 'match',
value: 'some value',
} as Entry & { id: string },
],
};
expect(output).toEqual(expectedOutput);
});
it('should return same output as input with added ids per nested entry', () => {
const mockExceptionItem: ExceptionListItemSchema = {
...getExceptionListItemSchemaMock(),
entries: [
{
entries: [
{
field: 'nested.field',
operator: 'included',
type: 'match',
value: 'some value',
},
],
field: 'some.parentField',
type: 'nested',
},
],
};
const output = addIdToExceptionItemEntries(mockExceptionItem);
const expectedOutput: ExceptionListItemSchema = {
...getExceptionListItemSchemaMock(),
entries: [
{
entries: [
{
field: 'nested.field',
id: '123',
operator: 'included',
type: 'match',
value: 'some value',
} as EntryMatch & { id: string },
],
field: 'some.parentField',
id: '123',
type: 'nested',
} as EntryNested & { id: string },
],
};
expect(output).toEqual(expectedOutput);
});
});
describe('removeIdFromExceptionItemsEntries', () => {
it('should return same output as input with stripped ids per entry - CreateExceptionListItemSchema', () => {
const mockCreateExceptionItem = {
...getCreateExceptionListItemSchemaMock(),
entries: [
{
field: 'some.not.nested.field',
id: '123',
operator: 'included',
type: 'match',
value: 'some value',
} as Entry & { id: string },
],
};
const output = removeIdFromExceptionItemsEntries(mockCreateExceptionItem);
const expectedOutput: CreateExceptionListItemSchema = {
...getCreateExceptionListItemSchemaMock(),
entries: [
{
field: 'some.not.nested.field',
operator: 'included',
type: 'match',
value: 'some value',
},
],
};
expect(output).toEqual(expectedOutput);
});
it('should return same output as input with stripped ids per nested entry - CreateExceptionListItemSchema', () => {
const mockCreateExceptionItem = {
...getCreateExceptionListItemSchemaMock(),
entries: [
{
entries: [
{
field: 'nested.field',
id: '123',
operator: 'included',
type: 'match',
value: 'some value',
} as EntryMatch & { id: string },
],
field: 'some.parentField',
id: '123',
type: 'nested',
} as EntryNested & { id: string },
],
};
const output = removeIdFromExceptionItemsEntries(mockCreateExceptionItem);
const expectedOutput: CreateExceptionListItemSchema = {
...getCreateExceptionListItemSchemaMock(),
entries: [
{
entries: [
{
field: 'nested.field',
operator: 'included',
type: 'match',
value: 'some value',
},
],
field: 'some.parentField',
type: 'nested',
},
],
};
expect(output).toEqual(expectedOutput);
});
it('should return same output as input with stripped ids per entry - UpdateExceptionListItemSchema', () => {
const mockUpdateExceptionItem = {
...getUpdateExceptionListItemSchemaMock(),
entries: [
{
field: 'some.not.nested.field',
id: '123',
operator: 'included',
type: 'match',
value: 'some value',
} as Entry & { id: string },
],
};
const output = removeIdFromExceptionItemsEntries(mockUpdateExceptionItem);
const expectedOutput: UpdateExceptionListItemSchema = {
...getUpdateExceptionListItemSchemaMock(),
entries: [
{
field: 'some.not.nested.field',
operator: 'included',
type: 'match',
value: 'some value',
},
],
};
expect(output).toEqual(expectedOutput);
});
it('should return same output as input with stripped ids per nested entry - UpdateExceptionListItemSchema', () => {
const mockUpdateExceptionItem = {
...getUpdateExceptionListItemSchemaMock(),
entries: [
{
entries: [
{
field: 'nested.field',
id: '123',
operator: 'included',
type: 'match',
value: 'some value',
} as EntryMatch & { id: string },
],
field: 'some.parentField',
id: '123',
type: 'nested',
} as EntryNested & { id: string },
],
};
const output = removeIdFromExceptionItemsEntries(mockUpdateExceptionItem);
const expectedOutput: UpdateExceptionListItemSchema = {
...getUpdateExceptionListItemSchemaMock(),
entries: [
{
entries: [
{
field: 'nested.field',
operator: 'included',
type: 'match',
value: 'some value',
},
],
field: 'some.parentField',
type: 'nested',
},
],
};
expect(output).toEqual(expectedOutput);
});
});
});

View file

@ -36,7 +36,10 @@ import type {
export const transformOutput = (
exceptionItem: UpdateExceptionListItemSchema | ExceptionListItemSchema
): UpdateExceptionListItemSchema | ExceptionListItemSchema =>
flow(removeIdFromExceptionItemsEntries)(exceptionItem);
flow(
removeCreatedAtCreatedByFromCommentsOnUpdate,
removeIdFromExceptionItemsEntries
)(exceptionItem);
export const transformNewItemOutput = (
exceptionItem: CreateExceptionListItemSchema
@ -112,3 +115,23 @@ export const removeIdFromExceptionItemsEntries = <T extends { entries: EntriesAr
});
return { ...exceptionItem, entries: entriesNoId };
};
/**
* This removes createdAt, createdBy from the exceptionItem if a comment was added to
* the Exception item, and return the comment message with id to prevent creating the commet
* twice
* @param exceptionItem The exceptionItem to remove createdAt, createdBy from the comments array.
* @returns exceptionItem The exceptionItem with comments do not have createdAt, createdBy.
*/
export const removeCreatedAtCreatedByFromCommentsOnUpdate = (
exceptionItem: UpdateExceptionListItemSchema | ExceptionListItemSchema
) => {
const { comments } = exceptionItem;
if (!comments || !comments.length) return exceptionItem;
const entriesNoCreatedAtAndBy = comments.map(({ comment, id }) => ({
comment,
id,
}));
return { ...exceptionItem, comments: entriesNoCreatedAtAndBy };
};

View file

@ -27,8 +27,8 @@ import type {
ExceptionListSchema,
} from '@kbn/securitysolution-io-ts-list-types';
import {
updateExceptionListItemSchema,
ExceptionListTypeEnum,
exceptionListItemSchema,
} from '@kbn/securitysolution-io-ts-list-types';
import type { ExceptionsBuilderReturnExceptionItem } from '@kbn/securitysolution-list-utils';
@ -237,7 +237,7 @@ const EditExceptionFlyoutComponent: React.FC<EditExceptionFlyoutProps> = ({
const areItemsReadyForUpdate = useCallback(
(items: ExceptionsBuilderReturnExceptionItem[]): items is ExceptionListItemSchema[] => {
return items.every((item) => exceptionListItemSchema.is(item));
return items.every((item) => updateExceptionListItemSchema.is(item));
},
[]
);