Skip to content

Commit

Permalink
[SEIM][Detection Engine] Moves the io-ts schemas to the common folder…
Browse files Browse the repository at this point in the history
… from the server side

## Summary

This moves the io-ts schemas from the common folder from the server side up to the common folder.

### Checklist

- [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios
  • Loading branch information
FrankHassanabad committed Jun 1, 2020
1 parent 571b3de commit 0dca28b
Show file tree
Hide file tree
Showing 48 changed files with 333 additions and 535 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,10 @@ import { pipe } from 'fp-ts/lib/pipeable';

import { getErrorPayload } from './__mocks__/utils';
import { errorSchema, ErrorSchema } from './error_schema';
import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags';
import { exactCheck } from '../../../../../../common/exact_check';
import { getPaths, foldLeftRight } from '../../../../../../common/test_utils';
import { exactCheck } from '../../../exact_check';
import { foldLeftRight, getPaths } from '../../../test_utils';

describe('error_schema', () => {
beforeAll(() => {
setFeatureFlagsForTestsOnly();
});

afterAll(() => {
unSetFeatureFlagsForTestsOnly();
});

test('it should validate an error with a UUID given for id', () => {
const error = getErrorPayload();
const decoded = errorSchema.decode(getErrorPayload());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import * as t from 'io-ts';

/* eslint-disable @typescript-eslint/camelcase */
import { rule_id, status_code, message } from './schemas';
import { rule_id, status_code, message } from '../common/schemas';
/* eslint-enable @typescript-eslint/camelcase */

// We use id: t.string intentionally and _never_ the id from global schemas as
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,10 @@ import { pipe } from 'fp-ts/lib/pipeable';
import { getFindResponseSingle, getBaseResponsePayload } from './__mocks__/utils';
import { left } from 'fp-ts/lib/Either';
import { RulesSchema } from './rules_schema';
import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags';
import { getPaths, foldLeftRight } from '../../../../../../common/test_utils';
import { exactCheck } from '../../../../../../common/exact_check';
import { exactCheck } from '../../../exact_check';
import { foldLeftRight, getPaths } from '../../../test_utils';

describe('find_rules_schema', () => {
beforeAll(() => {
setFeatureFlagsForTestsOnly();
});

afterAll(() => {
unSetFeatureFlagsForTestsOnly();
});

test('it should validate a typical single find rules response', () => {
const payload = getFindResponseSingle();
const decoded = findRulesSchema.decode(payload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import * as t from 'io-ts';

import { rulesSchema } from './rules_schema';
import { page, perPage, total } from './schemas';
import { page, perPage, total } from '../common/schemas';

export const findRulesSchema = t.exact(
t.type({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,11 @@ import { pipe } from 'fp-ts/lib/pipeable';
import { left, Either } from 'fp-ts/lib/Either';
import { ImportRulesSchema, importRulesSchema } from './import_rules_schema';
import { ErrorSchema } from './error_schema';
import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags';
import { Errors } from 'io-ts';
import { exactCheck } from '../../../../../../common/exact_check';
import { foldLeftRight, getPaths } from '../../../../../../common/test_utils';
import { exactCheck } from '../../../exact_check';
import { foldLeftRight, getPaths } from '../../../test_utils';

describe('import_rules_schema', () => {
beforeAll(() => {
setFeatureFlagsForTestsOnly();
});

afterAll(() => {
unSetFeatureFlagsForTestsOnly();
});

test('it should validate an empty import response with no errors', () => {
const payload: ImportRulesSchema = { success: true, success_count: 0, errors: [] };
const decoded = importRulesSchema.decode(payload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import * as t from 'io-ts';

/* eslint-disable @typescript-eslint/camelcase */
import { success, success_count } from './schemas';
import { success, success_count } from '../common/schemas';
import { errorSchema } from './error_schema';
/* eslint-enable @typescript-eslint/camelcase */

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,10 @@
import { pipe } from 'fp-ts/lib/pipeable';
import { left } from 'fp-ts/lib/Either';
import { PrePackagedRulesSchema, prePackagedRulesSchema } from './prepackaged_rules_schema';
import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags';
import { exactCheck } from '../../../../../../common/exact_check';
import { getPaths, foldLeftRight } from '../../../../../../common/test_utils';
import { exactCheck } from '../../../exact_check';
import { foldLeftRight, getPaths } from '../../../test_utils';

describe('prepackaged_rules_schema', () => {
beforeAll(() => {
setFeatureFlagsForTestsOnly();
});

afterAll(() => {
unSetFeatureFlagsForTestsOnly();
});

test('it should validate an empty prepackaged response with defaults', () => {
const payload: PrePackagedRulesSchema = { rules_installed: 0, rules_updated: 0 };
const decoded = prePackagedRulesSchema.decode(payload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import * as t from 'io-ts';

/* eslint-disable @typescript-eslint/camelcase */
import { rules_installed, rules_updated } from './schemas';
import { rules_installed, rules_updated } from '../common/schemas';
/* eslint-enable @typescript-eslint/camelcase */

export const prePackagedRulesSchema = t.exact(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,10 @@ import {
PrePackagedRulesStatusSchema,
prePackagedRulesStatusSchema,
} from './prepackaged_rules_status_schema';
import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags';
import { exactCheck } from '../../../../../../common/exact_check';
import { foldLeftRight, getPaths } from '../../../../../../common/test_utils';
import { exactCheck } from '../../../exact_check';
import { foldLeftRight, getPaths } from '../../../test_utils';

describe('prepackaged_rules_schema', () => {
beforeAll(() => {
setFeatureFlagsForTestsOnly();
});

afterAll(() => {
unSetFeatureFlagsForTestsOnly();
});

test('it should validate an empty prepackaged response with defaults', () => {
const payload: PrePackagedRulesStatusSchema = {
rules_installed: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
rules_custom_installed,
rules_not_installed,
rules_not_updated,
} from './schemas';
} from '../common/schemas';
/* eslint-enable @typescript-eslint/camelcase */

export const prePackagedRulesStatusSchema = t.exact(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,10 @@ import { getBaseResponsePayload, getErrorPayload } from './__mocks__/utils';
import { RulesBulkSchema, rulesBulkSchema } from './rules_bulk_schema';
import { RulesSchema } from './rules_schema';
import { ErrorSchema } from './error_schema';
import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags';
import { exactCheck } from '../../../../../../common/exact_check';
import { foldLeftRight, getPaths } from '../../../../../../common/test_utils';
import { exactCheck } from '../../../exact_check';
import { foldLeftRight, getPaths } from '../../../test_utils';

describe('prepackaged_rule_schema', () => {
beforeAll(() => {
setFeatureFlagsForTestsOnly();
});

afterAll(() => {
unSetFeatureFlagsForTestsOnly();
});

test('it should validate a regular message and and error together with a uuid', () => {
const payload: RulesBulkSchema = [getBaseResponsePayload(), getErrorPayload()];
const decoded = rulesBulkSchema.decode(payload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,209 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { left } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import * as t from 'io-ts';

import {
rulesSchema,
RulesSchema,
checkTypeDependents,
getDependents,
addSavedId,
addTimelineTitle,
addQueryFields,
addTimelineTitle,
addMlFields,
} from './check_type_dependents';
} from './rules_schema';
import { getBaseResponsePayload, getMlRuleResponsePayload } from './__mocks__/utils';
import { left } from 'fp-ts/lib/Either';
import { RulesSchema } from './rules_schema';
import { exactCheck } from '../../../exact_check';
import { foldLeftRight, getPaths } from '../../../test_utils';
import { TypeAndTimelineOnly } from './type_timeline_only_schema';
import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags';
import { exactCheck } from '../../../../../../common/exact_check';
import { foldLeftRight, getPaths } from '../../../../../../common/test_utils';

describe('check_type_dependents', () => {
beforeAll(() => {
setFeatureFlagsForTestsOnly();
export const ANCHOR_DATE = '2020-02-20T03:57:54.037Z';

describe('rules_schema', () => {
test('it should validate a type of "query" without anything extra', () => {
const payload = getBaseResponsePayload();

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
const expected = getBaseResponsePayload();

expect(getPaths(left(message.errors))).toEqual([]);
expect(message.schema).toEqual(expected);
});

test('it should NOT validate a type of "query" when it has extra data', () => {
const payload: RulesSchema & { invalid_extra_data?: string } = getBaseResponsePayload();
payload.invalid_extra_data = 'invalid_extra_data';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual(['invalid keys "invalid_extra_data"']);
expect(message.schema).toEqual({});
});

test('it should NOT validate invalid_data for the type', () => {
const payload: Omit<RulesSchema, 'type'> & { type: string } = getBaseResponsePayload();
payload.type = 'invalid_data';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual([
'Invalid value "invalid_data" supplied to "type"',
]);
expect(message.schema).toEqual({});
});

test('it should NOT validate a type of "query" with a saved_id together', () => {
const payload = getBaseResponsePayload();
payload.type = 'query';
payload.saved_id = 'save id 123';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual(['invalid keys "saved_id"']);
expect(message.schema).toEqual({});
});

test('it should validate a type of "saved_query" with a "saved_id" dependent', () => {
const payload = getBaseResponsePayload();
payload.type = 'saved_query';
payload.saved_id = 'save id 123';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
const expected = getBaseResponsePayload();

expected.type = 'saved_query';
expected.saved_id = 'save id 123';

expect(getPaths(left(message.errors))).toEqual([]);
expect(message.schema).toEqual(expected);
});

test('it should NOT validate a type of "saved_query" without a "saved_id" dependent', () => {
const payload = getBaseResponsePayload();
payload.type = 'saved_query';
delete payload.saved_id;

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "saved_id"',
]);
expect(message.schema).toEqual({});
});

test('it should NOT validate a type of "saved_query" when it has extra data', () => {
const payload: RulesSchema & { invalid_extra_data?: string } = getBaseResponsePayload();
payload.type = 'saved_query';
payload.saved_id = 'save id 123';
payload.invalid_extra_data = 'invalid_extra_data';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual(['invalid keys "invalid_extra_data"']);
expect(message.schema).toEqual({});
});

test('it should validate a type of "timeline_id" if there is a "timeline_title" dependent', () => {
const payload = getBaseResponsePayload();
payload.timeline_id = 'some timeline id';
payload.timeline_title = 'some timeline title';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
const expected = getBaseResponsePayload();
expected.timeline_id = 'some timeline id';
expected.timeline_title = 'some timeline title';

expect(getPaths(left(message.errors))).toEqual([]);
expect(message.schema).toEqual(expected);
});

afterAll(() => {
unSetFeatureFlagsForTestsOnly();
test('it should NOT validate a type of "timeline_id" if there is "timeline_title" dependent when it has extra invalid data', () => {
const payload: RulesSchema & { invalid_extra_data?: string } = getBaseResponsePayload();
payload.timeline_id = 'some timeline id';
payload.timeline_title = 'some timeline title';
payload.invalid_extra_data = 'invalid_extra_data';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual(['invalid keys "invalid_extra_data"']);
expect(message.schema).toEqual({});
});

test('it should NOT validate a type of "timeline_id" if there is NOT a "timeline_title" dependent', () => {
const payload = getBaseResponsePayload();
payload.timeline_id = 'some timeline id';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "timeline_title"',
]);
expect(message.schema).toEqual({});
});

test('it should NOT validate a type of "timeline_title" if there is NOT a "timeline_id" dependent', () => {
const payload = getBaseResponsePayload();
payload.timeline_title = 'some timeline title';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual(['invalid keys "timeline_title"']);
expect(message.schema).toEqual({});
});

test('it should NOT validate a type of "saved_query" with a "saved_id" dependent and a "timeline_title" but there is NOT a "timeline_id"', () => {
const payload = getBaseResponsePayload();
payload.saved_id = 'some saved id';
payload.type = 'saved_query';
payload.timeline_title = 'some timeline title';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual(['invalid keys "timeline_title"']);
expect(message.schema).toEqual({});
});

test('it should NOT validate a type of "saved_query" with a "saved_id" dependent and a "timeline_id" but there is NOT a "timeline_title"', () => {
const payload = getBaseResponsePayload();
payload.saved_id = 'some saved id';
payload.type = 'saved_query';
payload.timeline_id = 'some timeline id';

const decoded = rulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "timeline_title"',
]);
expect(message.schema).toEqual({});
});

describe('checkTypeDependents', () => {
Expand Down
Loading

0 comments on commit 0dca28b

Please sign in to comment.