Skip to content

Commit

Permalink
Merge branch 'main' into versioning-all-ml-apis
Browse files Browse the repository at this point in the history
  • Loading branch information
jgowdyelastic authored May 17, 2023
2 parents 03d60fe + af91ecc commit 7b1c693
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export const CREATE_MAINTENANCE_WINDOW_DESCRIPTION = i18n.translate(
'xpack.alerting.maintenanceWindows.create.description',
{
defaultMessage:
'Schedule a single or recurring period in which rule notifications cease and alerts are in maintenance mode.',
'Schedule a single or recurring period in which new alerts do not send notifications.',
}
);

Expand Down
17 changes: 3 additions & 14 deletions x-pack/plugins/cases/server/client/attachments/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,7 @@ import type {
} from '../../../common/api';
import type { FindCommentsArgs, GetAllAlertsAttachToCase, GetAllArgs, GetArgs } from './types';

import {
CASE_COMMENT_SAVED_OBJECT,
CASE_SAVED_OBJECT,
MAX_DOCS_PER_PAGE,
} from '../../../common/constants';
import { CASE_COMMENT_SAVED_OBJECT, CASE_SAVED_OBJECT } from '../../../common/constants';
import {
FindCommentsArgsRt,
CommentType,
Expand All @@ -48,6 +44,7 @@ import { createCaseError } from '../../common/error';
import { DEFAULT_PAGE, DEFAULT_PER_PAGE } from '../../routes/api';
import { buildFilter, combineFilters } from '../utils';
import { Operations } from '../../authorization';
import { validateFindCommentsPagination } from './validators';

const normalizeAlertResponse = (alerts: Array<SavedObject<AttributesTypeAlerts>>): AlertResponse =>
alerts.reduce((acc: AlertResponse, alert) => {
Expand Down Expand Up @@ -131,15 +128,7 @@ export async function find(
fold(throwErrors(Boom.badRequest), identity)
);

if (
queryParams?.page &&
queryParams?.perPage &&
queryParams?.page * queryParams?.perPage > MAX_DOCS_PER_PAGE
) {
throw Boom.badRequest(
'The number of documents is too high. Paginating through more than 10,000 documents is not possible.'
);
}
validateFindCommentsPagination(queryParams);

try {
const { filter: authorizationFilter, ensureSavedObjectsAreAuthorized } =
Expand Down
39 changes: 39 additions & 0 deletions x-pack/plugins/cases/server/client/attachments/validators.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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 { validateFindCommentsPagination } from './validators';

const ERROR_MSG =
'The number of documents is too high. Paginating through more than 10,000 documents is not possible.';

describe('validators', () => {
describe('validateFindCommentsPagination', () => {
it('does not throw if only page is undefined', () => {
expect(() => validateFindCommentsPagination({ perPage: 100 })).not.toThrowError();
});

it('does not throw if only perPage is undefined', () => {
expect(() => validateFindCommentsPagination({ page: 100 })).not.toThrowError();
});

it('returns if page and perPage are undefined', () => {
expect(() => validateFindCommentsPagination({})).not.toThrowError();
});

it('throws if page > 10k', () => {
expect(() => validateFindCommentsPagination({ page: 10001 })).toThrow(ERROR_MSG);
});

it('throws if perPage > 10k', () => {
expect(() => validateFindCommentsPagination({ perPage: 10001 })).toThrowError(ERROR_MSG);
});

it('throws if page * perPage > 10k', () => {
expect(() => validateFindCommentsPagination({ page: 10, perPage: 1001 })).toThrow(ERROR_MSG);
});
});
});
18 changes: 17 additions & 1 deletion x-pack/plugins/cases/server/client/attachments/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
*/

import Boom from '@hapi/boom';
import { MAX_DOCS_PER_PAGE } from '../../../common/constants';
import {
isCommentRequestTypeExternalReference,
isCommentRequestTypePersistableState,
} from '../../../common/utils/attachments';
import type { CommentRequest } from '../../../common/api';
import type { CommentRequest, FindCommentsQueryParams } from '../../../common/api';
import type { ExternalReferenceAttachmentTypeRegistry } from '../../attachment_framework/external_reference_registry';
import type { PersistableStateAttachmentTypeRegistry } from '../../attachment_framework/persistable_state_registry';

Expand Down Expand Up @@ -41,3 +42,18 @@ export const validateRegisteredAttachments = ({
);
}
};

export const validateFindCommentsPagination = (params?: FindCommentsQueryParams) => {
if (params?.page == null && params?.perPage == null) {
return;
}

const pageAsNumber = params.page ?? 0;
const perPageAsNumber = params.perPage ?? 0;

if (Math.max(pageAsNumber, perPageAsNumber, pageAsNumber * perPageAsNumber) > MAX_DOCS_PER_PAGE) {
throw Boom.badRequest(
'The number of documents is too high. Paginating through more than 10,000 documents is not possible.'
);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@

import expect from '@kbn/expect';

import {
CASES_URL,
INTERNAL_BULK_CREATE_ATTACHMENTS_URL,
} from '@kbn/cases-plugin/common/constants';
import { CASES_URL } from '@kbn/cases-plugin/common/constants';
import { CommentType } from '@kbn/cases-plugin/common/api';
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
import {
Expand All @@ -32,6 +29,7 @@ import {
getSpaceUrlPrefix,
createCase,
findAttachments,
bulkCreateAttachments,
} from '../../../../common/lib/api';

import {
Expand All @@ -58,122 +56,85 @@ export default ({ getService }: FtrProviderContext): void => {
});

it('should find all case comment', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const postedCase = await createCase(supertest, postCaseReq, 200);

// post 2 comments
await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentUserReq)
.expect(200);
await createComment({
supertest,
caseId: postedCase.id,
params: postCommentUserReq,
expectedHttpCode: 200,
});

const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentUserReq)
.expect(200);
const patchedCase = await createComment({
supertest,
caseId: postedCase.id,
params: postCommentUserReq,
expectedHttpCode: 200,
});

const { body: caseComments } = await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/_find`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
const caseComments = await findAttachments({
supertest,
caseId: postedCase.id,
expectedHttpCode: 200,
});

expect(caseComments.comments).to.eql(patchedCase.comments);
});

it('should find only case comments of the correct type', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const postedCase = await createCase(supertest, postCaseReq, 200);

// post 5 comments of all possible types
await supertest
.post(INTERNAL_BULK_CREATE_ATTACHMENTS_URL.replace('{case_id}', postedCase.id))
.set('kbn-xsrf', 'true')
.send([
await bulkCreateAttachments({
supertest,
caseId: postedCase.id,
params: [
postCommentUserReq,
postCommentAlertReq,
postCommentActionsReq,
postExternalReferenceESReq,
persistableStateAttachment,
])
.expect(200);
],
expectedHttpCode: 200,
});

const { body: caseComments } = await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/_find`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
const caseComments = await findAttachments({
supertest,
caseId: postedCase.id,
expectedHttpCode: 200,
});

expect(caseComments.comments.length).to.eql(1);
expect(caseComments.comments[0].type).to.eql(CommentType.user);
});

it('unhappy path - 400s when query is wrong type', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);

await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentUserReq)
.expect(200);

await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/_find?perPage=true`)
.set('kbn-xsrf', 'true')
.send()
.expect(400);
});

it('unhappy path - 400s when field is unkown', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);

await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentUserReq)
.expect(200);

await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/_find?foobar=true`)
.set('kbn-xsrf', 'true')
.send()
.expect(400);
});

it('unhappy path - 400s when total items invalid', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
describe('unhappy paths', () => {
for (const errorScenario of [
{ name: 'field is wrong type', queryParams: { perPage: true } },
{ name: 'field is unknown', queryParams: { foo: 'bar' } },
{ name: 'page > 10k', queryParams: { page: 10001 } },
{ name: 'perPage > 10k', queryParams: { perPage: 10001 } },
{ name: 'page * perPage > 10k', queryParams: { page: 2, perPage: 9001 } },
]) {
it(`400s when ${errorScenario.name}`, async () => {
const postedCase = await createCase(supertest, postCaseReq, 200);

await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentUserReq)
.expect(200);
await createComment({
supertest,
caseId: postedCase.id,
params: postCommentUserReq,
expectedHttpCode: 200,
});

await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/_find?page=2&perPage=9001`)
.set('kbn-xsrf', 'true')
.send()
.expect(400);
await findAttachments({
supertest,
caseId: postedCase.id,
query: errorScenario.queryParams,
expectedHttpCode: 400,
});
});
}
});

describe('rbac', () => {
Expand Down Expand Up @@ -333,11 +294,6 @@ export default ({ getService }: FtrProviderContext): void => {

await supertest.get(`${CASES_URL}/${obsCase.id}/comments/_find?namespaces=*`).expect(400);
});

it('should NOT allow to pass a non supported query parameter', async () => {
await supertest.get(`${CASES_URL}/id/comments/_find?notExists=papa`).expect(400);
await supertest.get(`${CASES_URL}/id/comments/_find?owner=papa`).expect(400);
});
});
});
};
17 changes: 14 additions & 3 deletions x-pack/test/functional/apps/infra/metrics_explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,21 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
});

// FLAKY: https://github.com/elastic/kibana/issues/157738
describe.skip('Saved Views', () => {
describe('Saved Views', () => {
before(async () => {
await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs');
await pageObjects.infraHome.goToMetricExplorer();
});

after(() => esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'));

beforeEach(async () => {
await pageObjects.infraSavedViews.clickSavedViewsButton();
});
afterEach(async () => {
await pageObjects.infraSavedViews.closeSavedViewsPopover();
});

it('should render a button with the view name', async () => {
await pageObjects.infraSavedViews.ensureViewIsLoaded('Default view');
});
Expand All @@ -125,7 +131,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});

it('should laod a clicked view from the manage views section', async () => {
await pageObjects.infraSavedViews.ensureViewIsLoaded('view1');
const views = await pageObjects.infraSavedViews.getManageViewsEntries();
await views[0].click();
await pageObjects.infraSavedViews.ensureViewIsLoaded('Default view');
Expand All @@ -136,14 +141,20 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
expect(views.length).to.equal(2);
await pageObjects.infraSavedViews.pressEsc();

await pageObjects.infraSavedViews.clickSavedViewsButton();
await pageObjects.infraSavedViews.createView('view2');
await pageObjects.infraSavedViews.ensureViewIsLoaded('view2');

await pageObjects.infraSavedViews.clickSavedViewsButton();
views = await pageObjects.infraSavedViews.getManageViewsEntries();
expect(views.length).to.equal(3);
await pageObjects.infraSavedViews.pressEsc();

await pageObjects.infraSavedViews.clickSavedViewsButton();
await pageObjects.infraSavedViews.updateView('view3');
await pageObjects.infraSavedViews.ensureViewIsLoaded('view3');

await pageObjects.infraSavedViews.clickSavedViewsButton();
views = await pageObjects.infraSavedViews.getManageViewsEntries();
expect(views.length).to.equal(3);
await pageObjects.infraSavedViews.pressEsc();
Expand Down
Loading

0 comments on commit 7b1c693

Please sign in to comment.