Re-enable brolen ML tests (#133510) (#133903)

(cherry picked from commit 3eb00f5933)

Co-authored-by: Dmitrii Shevchenko <dmitrii.shevchenko@elastic.co>
This commit is contained in:
Kibana Machine 2022-06-08 12:12:47 -04:00 committed by GitHub
parent 27f5777854
commit e734f48ff5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 253 additions and 165 deletions

View file

@ -865,6 +865,7 @@
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-react-perf": "^3.3.0",
"eslint-traverse": "^1.0.0",
"expect": "^28.1.1",
"expose-loader": "^0.7.5",
"faker": "^5.1.0",
"fancy-log": "^1.3.2",

View file

@ -66,7 +66,7 @@ describe('Detection rules, machine learning', () => {
visitWithoutDateRange(RULE_CREATION);
});
it.skip('Creates and enables a new ml rule', () => {
it('Creates and enables a new ml rule', () => {
selectMachineLearningRuleType();
fillDefineMachineLearningRuleAndContinue(getMachineLearningRule());
fillAboutRuleAndContinue(getMachineLearningRule());

View file

@ -321,7 +321,10 @@ export const getNewThresholdRule = (): ThresholdRule => ({
});
export const getMachineLearningRule = (): MachineLearningRule => ({
machineLearningJobs: ['linux_anomalous_network_service', 'linux_anomalous_network_activity_ecs'],
machineLearningJobs: [
'v3_linux_anomalous_process_all_hosts',
'v3_linux_anomalous_network_activity',
],
anomalyScoreThreshold: '20',
name: 'New ML Rule Test',
description: 'The new ML rule description.',

View file

@ -126,7 +126,7 @@ export const mockJobsSummaryResponse: MlSummaryJob[] = [
export const mockGetModuleResponse: Module[] = [
{
id: 'siem_auditbeat',
id: 'security_linux_v3',
title: 'SIEM Auditbeat',
description:
'Detect suspicious network activity and unusual processes in Auditbeat data (beta)',
@ -136,7 +136,7 @@ export const mockGetModuleResponse: Module[] = [
query: { bool: { filter: [{ term: { 'agent.type': 'auditbeat' } }] } },
jobs: [
{
id: 'rare_process_by_host_linux_ecs',
id: 'rare_process_by_host_linux',
config: {
job_type: 'anomaly_detector',
description: 'SIEM Auditbeat: Detect unusually rare processes on Linux (beta)',
@ -203,7 +203,7 @@ export const mockGetModuleResponse: Module[] = [
kibana: {},
},
{
id: 'siem_winlogbeat',
id: 'security_windows_v3',
title: 'SIEM Winlogbeat',
description: 'Detect unusual processes and network activity in Winlogbeat data (beta)',
type: 'Winlogbeat data',
@ -356,7 +356,7 @@ export const mockGetModuleResponse: Module[] = [
export const checkRecognizerSuccess: RecognizerModule[] = [
{
id: 'siem_auditbeat',
id: 'security_linux_v3',
title: 'SIEM Auditbeat',
query: { bool: { filter: [{ term: { 'agent.type': 'auditbeat' } }] } },
description:
@ -512,7 +512,7 @@ export const mockSecurityJobs: SecurityJob[] = [
earliestTimestampMs: 1569812391387,
latestResultsTimestampMs: 1571022900000,
isSingleMetricViewerJob: true,
moduleId: 'siem_auditbeat',
moduleId: 'security_linux_v3',
defaultIndexPattern: 'auditbeat-*',
isCompatible: true,
isInstalled: true,
@ -533,7 +533,7 @@ export const mockSecurityJobs: SecurityJob[] = [
datafeedIndices: ['auditbeat-*'],
datafeedState: 'stopped',
isSingleMetricViewerJob: true,
moduleId: 'siem_auditbeat',
moduleId: 'security_linux_v3',
defaultIndexPattern: 'auditbeat-*',
isCompatible: true,
isInstalled: true,
@ -555,7 +555,7 @@ export const mockSecurityJobs: SecurityJob[] = [
description: 'SIEM Winlogbeat: Detect unusually rare processes on Windows (beta)',
groups: ['process', 'siem', 'winlogbeat'],
defaultIndexPattern: 'winlogbeat-*',
moduleId: 'siem_winlogbeat',
moduleId: 'security_windows_v3',
isCompatible: false,
isInstalled: false,
isElasticJob: true,

View file

@ -46,7 +46,7 @@ describe('useSecurityJobs', () => {
(checkRecognizer as jest.Mock).mockResolvedValue(checkRecognizerSuccess);
});
it.skip('combines multiple ML calls into an array of SecurityJobs', async () => {
it('combines multiple ML calls into an array of SecurityJobs', async () => {
const expectedSecurityJob: SecurityJob = {
datafeedId: 'datafeed-siem-api-rare_process_linux_ecs',
datafeedIndices: ['auditbeat-*'],
@ -78,7 +78,7 @@ describe('useSecurityJobs', () => {
expect(result.current.jobs).toEqual(expect.arrayContaining([expectedSecurityJob]));
});
it.skip('returns those permissions', async () => {
it('returns those permissions', async () => {
const { result, waitForNextUpdate } = renderHook(() => useSecurityJobs(false));
await waitForNextUpdate();
@ -86,7 +86,7 @@ describe('useSecurityJobs', () => {
expect(result.current.isLicensed).toEqual(true);
});
it.skip('renders a toast error if an ML call fails', async () => {
it('renders a toast error if an ML call fails', async () => {
(getModules as jest.Mock).mockRejectedValue('whoops');
const { waitForNextUpdate } = renderHook(() => useSecurityJobs(false));
await waitForNextUpdate();
@ -103,7 +103,7 @@ describe('useSecurityJobs', () => {
(hasMlLicense as jest.Mock).mockReturnValue(false);
});
it.skip('returns empty jobs and false predicates', () => {
it('returns empty jobs and false predicates', () => {
const { result } = renderHook(() => useSecurityJobs(false));
expect(result.current.jobs).toEqual([]);

View file

@ -23,7 +23,7 @@ import {
describe('useSecurityJobsHelpers', () => {
describe('moduleToSecurityJob', () => {
test.skip('correctly converts module to SecurityJob', () => {
test('correctly converts module to SecurityJob', () => {
const securityJob = moduleToSecurityJob(
mockGetModuleResponse[0],
mockGetModuleResponse[0].jobs[0],
@ -47,48 +47,48 @@ describe('useSecurityJobsHelpers', () => {
jobState: 'closed',
jobTags: {},
memory_status: '',
moduleId: 'siem_auditbeat',
moduleId: 'security_linux_v3',
processed_record_count: 0,
});
});
describe('getAugmentedFields', () => {
test.skip('return correct augmented fields for given matching compatible modules', () => {
const moduleJobs = getModuleJobs(mockGetModuleResponse, ['siem_auditbeat']);
test('return correct augmented fields for given matching compatible modules', () => {
const moduleJobs = getModuleJobs(mockGetModuleResponse, ['security_linux_v3']);
const augmentedFields = getAugmentedFields('rare_process_by_host_linux', moduleJobs, [
'siem_auditbeat',
'security_linux_v3',
]);
expect(augmentedFields).toEqual({
defaultIndexPattern: 'auditbeat-*',
isCompatible: true,
isElasticJob: true,
moduleId: 'siem_auditbeat',
moduleId: 'security_linux_v3',
});
});
});
describe('getModuleJobs', () => {
test.skip('returns all jobs within a module for a compatible moduleId', () => {
const moduleJobs = getModuleJobs(mockGetModuleResponse, ['siem_auditbeat']);
test('returns all jobs within a module for a compatible moduleId', () => {
const moduleJobs = getModuleJobs(mockGetModuleResponse, ['security_linux_v3']);
expect(moduleJobs.length).toEqual(3);
});
});
describe('getInstalledJobs', () => {
test.skip('returns all jobs from jobSummary for a compatible moduleId', () => {
const moduleJobs = getModuleJobs(mockGetModuleResponse, ['siem_auditbeat']);
test('returns all jobs from jobSummary for a compatible moduleId', () => {
const moduleJobs = getModuleJobs(mockGetModuleResponse, ['security_linux_v3']);
const installedJobs = getInstalledJobs(mockJobsSummaryResponse, moduleJobs, [
'siem_auditbeat',
'security_linux_v3',
]);
expect(installedJobs.length).toEqual(3);
});
});
describe('composeModuleAndInstalledJobs', () => {
test.skip('returns correct number of jobs when composing separate module and installed jobs', () => {
const moduleJobs = getModuleJobs(mockGetModuleResponse, ['siem_auditbeat']);
test('returns correct number of jobs when composing separate module and installed jobs', () => {
const moduleJobs = getModuleJobs(mockGetModuleResponse, ['security_linux_v3']);
const installedJobs = getInstalledJobs(mockJobsSummaryResponse, moduleJobs, [
'siem_auditbeat',
'security_linux_v3',
]);
const securityJobs = composeModuleAndInstalledJobs(installedJobs, moduleJobs);
expect(securityJobs.length).toEqual(6);
@ -96,7 +96,7 @@ describe('useSecurityJobsHelpers', () => {
});
describe('createSecurityJobs', () => {
test.skip('returns correct number of jobs when creating jobs with successful responses', () => {
test('returns correct number of jobs when creating jobs with successful responses', () => {
const securityJobs = createSecurityJobs(
mockJobsSummaryResponse,
mockGetModuleResponse,

View file

@ -51,7 +51,7 @@ exports[`JobsTableComponent renders correctly against snapshot 1`] = `
"latestResultsTimestampMs": 1571022900000,
"latestTimestampMs": 1571022859393,
"memory_status": "ok",
"moduleId": "siem_auditbeat",
"moduleId": "security_linux_v3",
"processed_record_count": 32010,
},
Object {
@ -78,7 +78,7 @@ exports[`JobsTableComponent renders correctly against snapshot 1`] = `
"jobState": "closed",
"jobTags": Object {},
"memory_status": "ok",
"moduleId": "siem_auditbeat",
"moduleId": "security_linux_v3",
"processed_record_count": 0,
},
Object {
@ -103,7 +103,7 @@ exports[`JobsTableComponent renders correctly against snapshot 1`] = `
"jobState": "closed",
"jobTags": Object {},
"memory_status": "",
"moduleId": "siem_winlogbeat",
"moduleId": "security_windows_v3",
"processed_record_count": 0,
},
]

View file

@ -54,7 +54,7 @@ exports[`JobsTableFilters renders correctly against snapshot 1`] = `
"latestResultsTimestampMs": 1571022900000,
"latestTimestampMs": 1571022859393,
"memory_status": "ok",
"moduleId": "siem_auditbeat",
"moduleId": "security_linux_v3",
"processed_record_count": 32010,
},
Object {
@ -81,7 +81,7 @@ exports[`JobsTableFilters renders correctly against snapshot 1`] = `
"jobState": "closed",
"jobTags": Object {},
"memory_status": "ok",
"moduleId": "siem_auditbeat",
"moduleId": "security_linux_v3",
"processed_record_count": 0,
},
Object {
@ -106,7 +106,7 @@ exports[`JobsTableFilters renders correctly against snapshot 1`] = `
"jobState": "closed",
"jobTags": Object {},
"memory_status": "",
"moduleId": "siem_winlogbeat",
"moduleId": "security_windows_v3",
"processed_record_count": 0,
},
]

View file

@ -5,29 +5,31 @@
* 2.0.
*/
import expect from '@kbn/expect';
import {
ALERT_REASON,
ALERT_RULE_EXECUTION_UUID,
ALERT_RULE_NAMESPACE,
ALERT_RULE_PARAMETERS,
ALERT_RULE_UPDATED_AT,
ALERT_SEVERITY,
ALERT_RISK_SCORE,
ALERT_RULE_EXECUTION_UUID,
ALERT_RULE_PARAMETERS,
ALERT_SEVERITY,
ALERT_STATUS,
ALERT_UUID,
ALERT_WORKFLOW_STATUS,
SPACE_IDS,
VERSION,
} from '@kbn/rule-data-utils';
import { flattenWithPrefix } from '@kbn/securitysolution-rules';
import { MachineLearningCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request';
import {
ALERT_ANCESTORS,
ALERT_DEPTH,
ALERT_ORIGINAL_TIME,
} from '@kbn/security-solution-plugin/common/field_maps/field_names';
import expect from 'expect';
import {
createListsIndex,
deleteAllExceptions,
deleteListsIndex,
importFile,
} from '../../../lists_api_integration/utils';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createRule,
@ -35,12 +37,6 @@ import {
deleteAllAlerts,
getOpenSignals,
} from '../../utils';
import {
createListsIndex,
deleteAllExceptions,
deleteListsIndex,
importFile,
} from '../../../lists_api_integration/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
@ -49,8 +45,8 @@ export default ({ getService }: FtrProviderContext) => {
const es = getService('es');
const log = getService('log');
const siemModule = 'siem_auditbeat';
const mlJobId = 'linux_anomalous_network_activity_ecs';
const siemModule = 'security_linux_v3';
const mlJobId = 'v3_linux_anomalous_network_activity';
const testRule: MachineLearningCreateSchema = {
name: 'Test ML rule',
description: 'Test ML rule description',
@ -93,7 +89,7 @@ export default ({ getService }: FtrProviderContext) => {
}
// FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/125033
describe.skip('Generating signals from ml anomalies', () => {
describe('Generating signals from ml anomalies', () => {
before(async () => {
// Order is critical here: auditbeat data must be loaded before attempting to start the ML job,
// as the job looks for certain indices on start
@ -114,120 +110,77 @@ export default ({ getService }: FtrProviderContext) => {
it('should create 1 alert from ML rule when record meets anomaly_threshold', async () => {
const createdRule = await createRule(supertest, log, testRule);
const signalsOpen = await getOpenSignals(supertest, log, es, createdRule);
expect(signalsOpen.hits.hits.length).eql(1);
expect(signalsOpen.hits.hits.length).toBe(1);
const signal = signalsOpen.hits.hits[0];
if (!signal._source) {
return expect(signal._source).to.be.ok();
}
expect(signal._source).eql({
'@timestamp': signal._source['@timestamp'],
[ALERT_RULE_EXECUTION_UUID]: signal._source[ALERT_RULE_EXECUTION_UUID],
[ALERT_UUID]: signal._source[ALERT_UUID],
[VERSION]: signal._source[VERSION],
actual: [1],
bucket_span: 900,
by_field_name: 'process.name',
by_field_value: 'store',
detector_index: 0,
function: 'rare',
function_description: 'rare',
influencers: [
{ influencer_field_name: 'user.name', influencer_field_values: ['root'] },
{ influencer_field_name: 'process.name', influencer_field_values: ['store'] },
{ influencer_field_name: 'host.name', influencer_field_values: ['mothra'] },
],
initial_record_score: 33.36147565024334,
is_interim: false,
job_id: 'linux_anomalous_network_activity_ecs',
multi_bucket_impact: 0,
probability: 0.007820139656036713,
record_score: 33.36147565024334,
result_type: 'record',
timestamp: 1605567488000,
typical: [0.007820139656036711],
user: { name: ['root'] },
process: { name: ['store'] },
host: { name: ['mothra'] },
'event.kind': 'signal',
[ALERT_ANCESTORS]: [
{
id: 'linux_anomalous_network_activity_ecs_record_1586274300000_900_0_-96106189301704594950079884115725560577_5',
type: 'event',
index: '.ml-anomalies-custom-linux_anomalous_network_activity_ecs',
depth: 0,
expect(signal._source).toEqual(
expect.objectContaining({
'@timestamp': expect.any(String),
[ALERT_RULE_EXECUTION_UUID]: expect.any(String),
[ALERT_UUID]: expect.any(String),
[VERSION]: expect.any(String),
actual: [1],
bucket_span: expect.any(Number),
by_field_name: 'process.name',
by_field_value: 'store',
detector_index: 0,
function: 'rare',
function_description: 'rare',
influencers: expect.any(Array),
initial_record_score: expect.any(Number),
is_interim: false,
job_id: 'v3_linux_anomalous_network_activity',
multi_bucket_impact: expect.any(Number),
probability: expect.any(Number),
record_score: expect.any(Number),
result_type: 'record',
timestamp: expect.any(Number),
typical: expect.arrayContaining([expect.any(Number)]),
user: { name: ['root'] },
process: { name: ['store'] },
host: { name: ['mothra'] },
'event.kind': 'signal',
[ALERT_ANCESTORS]: expect.any(Array),
[ALERT_WORKFLOW_STATUS]: 'open',
[ALERT_STATUS]: 'active',
[SPACE_IDS]: ['default'],
[ALERT_SEVERITY]: 'critical',
[ALERT_RISK_SCORE]: 50,
[ALERT_RULE_PARAMETERS]: {
anomaly_threshold: 30,
author: [],
description: 'Test ML rule description',
exceptions_list: [],
false_positives: [],
from: '1900-01-01T00:00:00.000Z',
immutable: false,
machine_learning_job_id: ['v3_linux_anomalous_network_activity'],
max_signals: 100,
references: [],
related_integrations: [],
required_fields: [],
risk_score: 50,
risk_score_mapping: [],
rule_id: createdRule.rule_id,
setup: '',
severity: 'critical',
severity_mapping: [],
threat: [],
to: 'now',
type: 'machine_learning',
version: 1,
},
],
[ALERT_WORKFLOW_STATUS]: 'open',
[ALERT_STATUS]: 'active',
[SPACE_IDS]: ['default'],
[ALERT_SEVERITY]: 'critical',
[ALERT_RISK_SCORE]: 50,
[ALERT_RULE_PARAMETERS]: {
anomaly_threshold: 30,
author: [],
description: 'Test ML rule description',
exceptions_list: [],
false_positives: [],
from: '1900-01-01T00:00:00.000Z',
immutable: false,
machine_learning_job_id: ['linux_anomalous_network_activity_ecs'],
max_signals: 100,
references: [],
risk_score: 50,
risk_score_mapping: [],
rule_id: createdRule.rule_id,
severity: 'critical',
severity_mapping: [],
threat: [],
to: 'now',
type: 'machine_learning',
version: 1,
},
...flattenWithPrefix(ALERT_RULE_NAMESPACE, {
uuid: createdRule.id,
category: 'Machine Learning Rule',
consumer: 'siem',
producer: 'siem',
rule_id: createdRule.rule_id,
rule_type_id: 'siem.mlRule',
created_at: createdRule.created_at,
updated_at: signal._source?.[ALERT_RULE_UPDATED_AT],
actions: [],
interval: '5m',
name: 'Test ML rule',
tags: [],
enabled: true,
created_by: 'elastic',
updated_by: 'elastic',
description: 'Test ML rule description',
risk_score: 50,
severity: 'critical',
author: [],
false_positives: [],
from: '1900-01-01T00:00:00.000Z',
max_signals: 100,
risk_score_mapping: [],
severity_mapping: [],
threat: [],
to: 'now',
references: [],
version: 1,
exceptions_list: [],
immutable: false,
type: 'machine_learning',
}),
[ALERT_DEPTH]: 1,
[ALERT_REASON]: `event with process store, by root on mothra created critical alert Test ML rule.`,
[ALERT_ORIGINAL_TIME]: '2020-11-16T22:58:08.000Z',
all_field_values: [
'store',
'linux_anomalous_network_activity_ecs',
'root',
'store',
'mothra',
],
});
[ALERT_DEPTH]: 1,
[ALERT_REASON]: `event with process store, by root on mothra created critical alert Test ML rule.`,
[ALERT_ORIGINAL_TIME]: expect.any(String),
all_field_values: expect.arrayContaining([
'v3_linux_anomalous_network_activity',
'root',
'store',
'mothra',
]),
})
);
});
it('should create 7 alerts from ML rule when records meet anomaly_threshold', async () => {
@ -237,7 +190,7 @@ export default ({ getService }: FtrProviderContext) => {
};
const createdRule = await createRule(supertest, log, rule);
const signalsOpen = await getOpenSignals(supertest, log, es, createdRule);
expect(signalsOpen.hits.hits.length).eql(7);
expect(signalsOpen.hits.hits.length).toBe(7);
});
describe('with non-value list exception', () => {
@ -256,7 +209,7 @@ export default ({ getService }: FtrProviderContext) => {
],
]);
const signalsOpen = await getOpenSignals(supertest, log, es, createdRule);
expect(signalsOpen.hits.hits.length).equal(0);
expect(signalsOpen.hits.hits.length).toBe(0);
});
});
@ -287,7 +240,7 @@ export default ({ getService }: FtrProviderContext) => {
],
]);
const signalsOpen = await getOpenSignals(supertest, log, es, createdRule);
expect(signalsOpen.hits.hits.length).equal(0);
expect(signalsOpen.hits.hits.length).toBe(0);
});
});
});

131
yarn.lock
View file

@ -2413,6 +2413,13 @@
"@types/node" "*"
jest-mock "^26.6.2"
"@jest/expect-utils@^28.1.1":
version "28.1.1"
resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.1.tgz#d84c346025b9f6f3886d02c48a6177e2b0360587"
integrity sha512-n/ghlvdhCdMI/hTcnn4qV57kQuV9OTsZzH1TTCVARANKhl6hXJqLKUkwX69ftMGpsbpt96SsDD8n8LD2d9+FRw==
dependencies:
jest-get-type "^28.0.2"
"@jest/fake-timers@^24.9.0":
version "24.9.0"
resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93"
@ -2475,6 +2482,13 @@
optionalDependencies:
node-notifier "^8.0.0"
"@jest/schemas@^28.0.2":
version "28.0.2"
resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.0.2.tgz#08c30df6a8d07eafea0aef9fb222c5e26d72e613"
integrity sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA==
dependencies:
"@sinclair/typebox" "^0.23.3"
"@jest/source-map@^24.9.0":
version "24.9.0"
resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714"
@ -2575,6 +2589,18 @@
"@types/yargs" "^16.0.0"
chalk "^4.0.0"
"@jest/types@^28.1.1":
version "28.1.1"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.1.tgz#d059bbc80e6da6eda9f081f293299348bd78ee0b"
integrity sha512-vRXVqSg1VhDnB8bWcmvLzmg0Bt9CRKVgHPXqYwvWMX3TvAjeO+nRuK6+VdTKCtWOvYlmkF/HqNAL/z+N3B53Kw==
dependencies:
"@jest/schemas" "^28.0.2"
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/istanbul-reports" "^3.0.0"
"@types/node" "*"
"@types/yargs" "^17.0.8"
chalk "^4.0.0"
"@jimp/bmp@^0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.14.0.tgz#6df246026554f276f7b354047c6fff9f5b2b5182"
@ -4254,6 +4280,11 @@
resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df"
integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==
"@sinclair/typebox@^0.23.3":
version "0.23.5"
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.5.tgz#93f7b9f4e3285a7a9ade7557d9a8d36809cbc47d"
integrity sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==
"@sindresorhus/is@^0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
@ -7459,6 +7490,13 @@
dependencies:
"@types/yargs-parser" "*"
"@types/yargs@^17.0.8":
version "17.0.10"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.10.tgz#591522fce85d8739bca7b8bb90d048e4478d186a"
integrity sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==
dependencies:
"@types/yargs-parser" "*"
"@types/yauzl@^2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.1.tgz#d10f69f9f522eef3cf98e30afb684a1e1ec923af"
@ -10309,6 +10347,11 @@ ci-info@^3.1.1:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6"
integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==
ci-info@^3.2.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.1.tgz#58331f6f472a25fe3a50a351ae3052936c2c7f32"
integrity sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@ -12622,6 +12665,11 @@ diff-sequences@^27.5.1:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327"
integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==
diff-sequences@^28.1.1:
version "28.1.1"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6"
integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==
diff@5.0.0, diff@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
@ -14126,6 +14174,17 @@ expect@^27.0.2:
jest-message-util "^27.2.0"
jest-regex-util "^27.0.6"
expect@^28.1.1:
version "28.1.1"
resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.1.tgz#ca6fff65f6517cf7220c2e805a49c19aea30b420"
integrity sha512-/AANEwGL0tWBwzLNOvO0yUdy2D52jVdNXppOqswC49sxMN2cPWsGCQdzuIf9tj6hHoBQzNvx75JUYuQAckPo3w==
dependencies:
"@jest/expect-utils" "^28.1.1"
jest-get-type "^28.0.2"
jest-matcher-utils "^28.1.1"
jest-message-util "^28.1.1"
jest-util "^28.1.1"
expiry-js@0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/expiry-js/-/expiry-js-0.1.7.tgz#76be8c05e572bf936df40c1766448d0b3b2f555f"
@ -15632,6 +15691,11 @@ graceful-fs@^4.2.3, graceful-fs@^4.2.6:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
graceful-fs@^4.2.9:
version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
graphlib@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da"
@ -17821,6 +17885,16 @@ jest-diff@^27.2.0:
jest-get-type "^27.0.6"
pretty-format "^27.2.0"
jest-diff@^28.1.1:
version "28.1.1"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.1.tgz#1a3eedfd81ae79810931c63a1d0f201b9120106c"
integrity sha512-/MUUxeR2fHbqHoMMiffe/Afm+U8U4olFRJ0hiVG2lZatPJcnGxx292ustVu7bULhjV65IYMxRdploAKLbcrsyg==
dependencies:
chalk "^4.0.0"
diff-sequences "^28.1.1"
jest-get-type "^28.0.2"
pretty-format "^28.1.1"
jest-docblock@^26.0.0:
version "26.0.0"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5"
@ -17893,6 +17967,11 @@ jest-get-type@^27.0.6:
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe"
integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==
jest-get-type@^28.0.2:
version "28.0.2"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203"
integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==
jest-haste-map@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa"
@ -17986,6 +18065,16 @@ jest-matcher-utils@^27.2.0:
jest-get-type "^27.0.6"
pretty-format "^27.2.0"
jest-matcher-utils@^28.1.1:
version "28.1.1"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.1.tgz#a7c4653c2b782ec96796eb3088060720f1e29304"
integrity sha512-NPJPRWrbmR2nAJ+1nmnfcKKzSwgfaciCCrYZzVnNoxVoyusYWIjkBMNvu0RHJe7dNj4hH3uZOPZsQA+xAYWqsw==
dependencies:
chalk "^4.0.0"
jest-diff "^28.1.1"
jest-get-type "^28.0.2"
pretty-format "^28.1.1"
jest-message-util@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3"
@ -18030,6 +18119,21 @@ jest-message-util@^27.2.0:
slash "^3.0.0"
stack-utils "^2.0.3"
jest-message-util@^28.1.1:
version "28.1.1"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.1.tgz#60aa0b475cfc08c8a9363ed2fb9108514dd9ab89"
integrity sha512-xoDOOT66fLfmTRiqkoLIU7v42mal/SqwDKvfmfiWAdJMSJiU+ozgluO7KbvoAgiwIrrGZsV7viETjc8GNrA/IQ==
dependencies:
"@babel/code-frame" "^7.12.13"
"@jest/types" "^28.1.1"
"@types/stack-utils" "^2.0.0"
chalk "^4.0.0"
graceful-fs "^4.2.9"
micromatch "^4.0.4"
pretty-format "^28.1.1"
slash "^3.0.0"
stack-utils "^2.0.3"
jest-mock@^24.0.0, jest-mock@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6"
@ -18271,6 +18375,18 @@ jest-util@^26.0.0, jest-util@^26.6.2:
is-ci "^2.0.0"
micromatch "^4.0.2"
jest-util@^28.1.1:
version "28.1.1"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.1.tgz#ff39e436a1aca397c0ab998db5a51ae2b7080d05"
integrity sha512-FktOu7ca1DZSyhPAxgxB6hfh2+9zMoJ7aEQA759Z6p45NuO8mWcqujH+UdHlCm/V6JTWwDztM2ITCzU1ijJAfw==
dependencies:
"@jest/types" "^28.1.1"
"@types/node" "*"
chalk "^4.0.0"
ci-info "^3.2.0"
graceful-fs "^4.2.9"
picomatch "^2.2.3"
jest-validate@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec"
@ -22943,6 +23059,16 @@ pretty-format@^27.0.2, pretty-format@^27.2.0, pretty-format@^27.5.1:
ansi-styles "^5.0.0"
react-is "^17.0.1"
pretty-format@^28.1.1:
version "28.1.1"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.1.tgz#f731530394e0f7fcd95aba6b43c50e02d86b95cb"
integrity sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==
dependencies:
"@jest/schemas" "^28.0.2"
ansi-regex "^5.0.1"
ansi-styles "^5.0.0"
react-is "^18.0.0"
pretty-format@^3.8.0:
version "3.8.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385"
@ -23765,6 +23891,11 @@ react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^18.0.0:
version "18.1.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67"
integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==
react-lib-adler32@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/react-lib-adler32/-/react-lib-adler32-1.0.3.tgz#63df1aed274eabcc1c5067077ea281ec30888ba7"