mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Cases] Total users returned by suggested users API (#161329)
Connected to https://github.com/elastic/kibana/issues/146945 ## Summary | Description | Limit | Done? | Documented? | ------------- | ---- | :---: | ---- | | Total number of users returned by suggest users API | 10 | ✅ | No (internal) | ### Checklist Delete any items that are not applicable to this PR. - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [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
This commit is contained in:
parent
3eb387c7dd
commit
ec6bcd69b8
7 changed files with 150 additions and 3 deletions
|
@ -5,6 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { PathReporter } from 'io-ts/lib/PathReporter';
|
||||
import { MAX_SUGGESTED_PROFILES } from '../../constants';
|
||||
import { SuggestUserProfilesRequestRt, CaseUserProfileRt } from './user_profiles';
|
||||
|
||||
describe('userProfile', () => {
|
||||
|
@ -44,6 +46,21 @@ describe('userProfile', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('missing size parameter works correctly', () => {
|
||||
const query = SuggestUserProfilesRequestRt.decode({
|
||||
name: 'di maria',
|
||||
owners: ['benfica'],
|
||||
});
|
||||
|
||||
expect(query).toStrictEqual({
|
||||
_tag: 'Right',
|
||||
right: {
|
||||
name: 'di maria',
|
||||
owners: ['benfica'],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('removes foo:bar attributes from request', () => {
|
||||
const query = SuggestUserProfilesRequestRt.decode({ ...defaultRequest, foo: 'bar' });
|
||||
|
||||
|
@ -56,6 +73,24 @@ describe('userProfile', () => {
|
|||
},
|
||||
});
|
||||
});
|
||||
|
||||
it(`does not accept size param bigger than ${MAX_SUGGESTED_PROFILES}`, () => {
|
||||
const query = SuggestUserProfilesRequestRt.decode({
|
||||
...defaultRequest,
|
||||
size: MAX_SUGGESTED_PROFILES + 1,
|
||||
});
|
||||
|
||||
expect(PathReporter.report(query)).toContain('The size field cannot be more than 10.');
|
||||
});
|
||||
|
||||
it('does not accept size param lower than 1', () => {
|
||||
const query = SuggestUserProfilesRequestRt.decode({
|
||||
...defaultRequest,
|
||||
size: 0,
|
||||
});
|
||||
|
||||
expect(PathReporter.report(query)).toContain('The size field cannot be less than 1.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('CaseUserProfileRt', () => {
|
||||
|
|
|
@ -6,13 +6,19 @@
|
|||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import { MAX_SUGGESTED_PROFILES } from '../../constants';
|
||||
import { limitedNumberSchema } from '../../schema';
|
||||
|
||||
export const SuggestUserProfilesRequestRt = rt.intersection([
|
||||
rt.strict({
|
||||
name: rt.string,
|
||||
owners: rt.array(rt.string),
|
||||
}),
|
||||
rt.exact(rt.partial({ size: rt.number })),
|
||||
rt.exact(
|
||||
rt.partial({
|
||||
size: limitedNumberSchema({ fieldName: 'size', min: 1, max: MAX_SUGGESTED_PROFILES }),
|
||||
})
|
||||
),
|
||||
]);
|
||||
|
||||
export type SuggestUserProfilesRequest = rt.TypeOf<typeof SuggestUserProfilesRequestRt>;
|
||||
|
|
|
@ -124,6 +124,7 @@ export const MAX_COMMENT_LENGTH = 30000 as const;
|
|||
export const MAX_LENGTH_PER_TAG = 256 as const;
|
||||
export const MAX_TAGS_PER_CASE = 200 as const;
|
||||
export const MAX_DELETE_IDS_LENGTH = 100 as const;
|
||||
export const MAX_SUGGESTED_PROFILES = 10 as const;
|
||||
export const MAX_CASES_TO_UPDATE = 100 as const;
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,13 @@
|
|||
|
||||
import { PathReporter } from 'io-ts/lib/PathReporter';
|
||||
|
||||
import { limitedArraySchema, limitedStringSchema, NonEmptyString, paginationSchema } from '.';
|
||||
import {
|
||||
limitedArraySchema,
|
||||
limitedNumberSchema,
|
||||
limitedStringSchema,
|
||||
NonEmptyString,
|
||||
paginationSchema,
|
||||
} from '.';
|
||||
import { MAX_DOCS_PER_PAGE } from '../constants';
|
||||
|
||||
describe('schema', () => {
|
||||
|
@ -281,4 +287,36 @@ describe('schema', () => {
|
|||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('limitedNumberSchema', () => {
|
||||
it('works correctly the number is between min and max', () => {
|
||||
expect(
|
||||
PathReporter.report(limitedNumberSchema({ fieldName: 'foo', min: 0, max: 2 }).decode(1))
|
||||
).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"No errors!",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('fails when given a number that is lower than the minimum', () => {
|
||||
expect(
|
||||
PathReporter.report(limitedNumberSchema({ fieldName: 'foo', min: 1, max: 2 }).decode(0))
|
||||
).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"The foo field cannot be less than 1.",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('fails when given number that is higher than the maximum', () => {
|
||||
expect(
|
||||
PathReporter.report(limitedNumberSchema({ fieldName: 'foo', min: 1, max: 2 }).decode(3))
|
||||
).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"The foo field cannot be more than 2.",
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -134,3 +134,22 @@ export const paginationSchema = ({ maxPerPage }: { maxPerPage: number }) =>
|
|||
rt.identity,
|
||||
undefined
|
||||
);
|
||||
|
||||
export const limitedNumberSchema = ({ fieldName, min, max }: LimitedSchemaType) =>
|
||||
new rt.Type<number, number, unknown>(
|
||||
'LimitedNumber',
|
||||
rt.number.is,
|
||||
(input, context) =>
|
||||
either.chain(rt.number.validate(input, context), (s) => {
|
||||
if (s < min) {
|
||||
return rt.failure(input, context, `The ${fieldName} field cannot be less than ${min}.`);
|
||||
}
|
||||
|
||||
if (s > max) {
|
||||
return rt.failure(input, context, `The ${fieldName} field cannot be more than ${max}.`);
|
||||
}
|
||||
|
||||
return rt.success(s);
|
||||
}),
|
||||
rt.identity
|
||||
);
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { MAX_SUGGESTED_PROFILES } from '../../../common/constants';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
import { UserProfileService } from '.';
|
||||
|
||||
describe('suggest', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('throws with invalid size field', async () => {
|
||||
const mockLogger = loggingSystemMock.createLogger();
|
||||
const userProfileService = new UserProfileService(mockLogger);
|
||||
await expect(
|
||||
// @ts-ignore: irrelevant missing parameters
|
||||
userProfileService.suggest({
|
||||
body: {
|
||||
name: 'antonio',
|
||||
owners: [],
|
||||
size: MAX_SUGGESTED_PROFILES + 1,
|
||||
},
|
||||
})
|
||||
).rejects.toThrow(
|
||||
`Failed to retrieve suggested user profiles in service: Error: The size field cannot be more than ${MAX_SUGGESTED_PROFILES}.`
|
||||
);
|
||||
});
|
||||
});
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { APP_ID as CASES_APP_ID } from '@kbn/cases-plugin/common/constants';
|
||||
import { APP_ID as CASES_APP_ID, MAX_SUGGESTED_PROFILES } from '@kbn/cases-plugin/common/constants';
|
||||
import { APP_ID as SECURITY_SOLUTION_APP_ID } from '@kbn/security-solution-plugin/common/constants';
|
||||
import { observabilityFeatureId as OBSERVABILITY_APP_ID } from '@kbn/observability-plugin/common';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
@ -76,5 +76,20 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('errors', () => {
|
||||
it('400s when size parameter is not valid', async () => {
|
||||
await suggestUserProfiles({
|
||||
supertest: supertestWithoutAuth,
|
||||
req: {
|
||||
name: casesAllUser.username,
|
||||
owners: [CASES_APP_ID],
|
||||
size: MAX_SUGGESTED_PROFILES + 1,
|
||||
},
|
||||
auth: { user: casesAllUser, space: null },
|
||||
expectedHttpCode: 400,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue