[ResponseOps][Cases] Make deprecated APIs internal in serverless (#198378)

## Summary
 
Fixes: https://github.com/elastic/kibana/issues/198407

### Checklist

Delete any items that are not applicable to this PR.

- [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

### For maintainers

- [x] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#_add_your_labels)
This commit is contained in:
Christos Nasikas 2024-11-01 09:38:32 +02:00 committed by GitHub
parent f5d9f0d40e
commit 2ae6333b1b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 483 additions and 171 deletions

View file

@ -122,9 +122,14 @@ export class CasePlugin
const router = core.http.createRouter<CasesRequestHandlerContext>();
const telemetryUsageCounter = plugins.usageCollection?.createUsageCounter(APP_ID);
const isServerless = plugins.cloud?.isServerlessEnabled;
registerRoutes({
router,
routes: [...getExternalRoutes(), ...getInternalRoutes(this.userProfileService)],
routes: [
...getExternalRoutes({ isServerless }),
...getInternalRoutes(this.userProfileService),
],
logger: this.logger,
kibanaVersion: this.kibanaVersion,
telemetryUsageCounter,

View file

@ -0,0 +1,62 @@
/*
* 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 { createCasesClientMock } from '../../../client/mocks';
import { getCaseRoute } from './get_case';
import { httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks';
describe('getCaseRoute', () => {
const casesClientMock = createCasesClientMock();
const logger = loggingSystemMock.createLogger();
const response = httpServerMock.createResponseFactory();
const kibanaVersion = '8.17';
const context = { cases: { getCasesClient: jest.fn().mockResolvedValue(casesClientMock) } };
it('throws a bad request if the includeComments is set in serverless', async () => {
const router = getCaseRoute({ isServerless: true });
const request = httpServerMock.createKibanaRequest({
path: '/api/cases/{case_id}/?includeComments=true',
query: { includeComments: true },
params: { case_id: 'foo' },
});
await expect(
// @ts-expect-error: no need to create the context
router.handler({ response, request, logger, kibanaVersion, context })
).rejects.toThrowErrorMatchingInlineSnapshot(`
"Failed to retrieve case in route case id: foo
include comments: true: Error: includeComments is not supported"
`);
});
it('does not throw a bad request if the includeComments is set in non-serverless', async () => {
const router = getCaseRoute({ isServerless: false });
const request = httpServerMock.createKibanaRequest({
path: '/api/cases/{case_id}/?includeComments=true',
query: { includeComments: true },
params: { case_id: 'foo' },
});
await expect(
// @ts-expect-error: no need to create the context
router.handler({ response, request, logger, kibanaVersion, context })
).resolves.not.toThrow();
});
it('does not throw a bad request if the includeComments is not set in serverless', async () => {
const router = getCaseRoute({ isServerless: true });
const request = httpServerMock.createKibanaRequest({
path: '/api/cases/{case_id}',
params: { case_id: 'foo' },
});
await expect(
// @ts-expect-error: no need to create the context
router.handler({ response, request, logger, kibanaVersion, context })
).resolves.not.toThrow();
});
});

View file

@ -5,6 +5,7 @@
* 2.0.
*/
import Boom from '@hapi/boom';
import { schema } from '@kbn/config-schema';
import type { caseApiV1 } from '../../../../common/types/api';
@ -26,53 +27,58 @@ const params = {
}),
};
export const getCaseRoute = createCasesRoute({
method: 'get',
path: CASE_DETAILS_URL,
params,
routerOptions: {
access: 'public',
summary: `Get a case`,
tags: ['oas-tag:cases'],
},
handler: async ({ context, request, response, logger, kibanaVersion }) => {
try {
const isIncludeCommentsParamProvidedByTheUser =
request.url.searchParams.has('includeComments');
export const getCaseRoute = ({ isServerless }: { isServerless?: boolean }) =>
createCasesRoute({
method: 'get',
path: CASE_DETAILS_URL,
params,
routerOptions: {
access: 'public',
summary: `Get a case`,
tags: ['oas-tag:cases'],
},
handler: async ({ context, request, response, logger, kibanaVersion }) => {
try {
const isIncludeCommentsParamProvidedByTheUser =
request.url.searchParams.has('includeComments');
if (isIncludeCommentsParamProvidedByTheUser) {
logDeprecatedEndpoint(
logger,
request.headers,
`The query parameter 'includeComments' of the get case API '${CASE_DETAILS_URL}' is deprecated`
);
if (isServerless && isIncludeCommentsParamProvidedByTheUser) {
throw Boom.badRequest('includeComments is not supported');
}
if (isIncludeCommentsParamProvidedByTheUser) {
logDeprecatedEndpoint(
logger,
request.headers,
`The query parameter 'includeComments' of the get case API '${CASE_DETAILS_URL}' is deprecated`
);
}
const caseContext = await context.cases;
const casesClient = await caseContext.getCasesClient();
const id = request.params.case_id;
const res: caseDomainV1.Case = await casesClient.cases.get({
id,
includeComments: request.query.includeComments,
});
return response.ok({
...(isIncludeCommentsParamProvidedByTheUser && {
headers: {
...getWarningHeader(kibanaVersion, 'Deprecated query parameter includeComments'),
},
}),
body: res,
});
} catch (error) {
throw createCaseError({
message: `Failed to retrieve case in route case id: ${request.params.case_id} \ninclude comments: ${request.query.includeComments}: ${error}`,
error,
});
}
const caseContext = await context.cases;
const casesClient = await caseContext.getCasesClient();
const id = request.params.case_id;
const res: caseDomainV1.Case = await casesClient.cases.get({
id,
includeComments: request.query.includeComments,
});
return response.ok({
...(isIncludeCommentsParamProvidedByTheUser && {
headers: {
...getWarningHeader(kibanaVersion, 'Deprecated query parameter includeComments'),
},
}),
body: res,
});
} catch (error) {
throw createCaseError({
message: `Failed to retrieve case in route case id: ${request.params.case_id} \ninclude comments: ${request.query.includeComments}: ${error}`,
error,
});
}
},
});
},
});
export const resolveCaseRoute = createCasesRoute({
method: 'get',

View file

@ -0,0 +1,22 @@
/*
* 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 { getAllCommentsRoute } from './get_all_comment';
describe('getAllCommentsRoute', () => {
it('marks the endpoint internal in serverless', async () => {
const router = getAllCommentsRoute({ isServerless: true });
expect(router.routerOptions?.access).toBe('internal');
});
it('marks the endpoint public in non-serverless', async () => {
const router = getAllCommentsRoute({ isServerless: false });
expect(router.routerOptions?.access).toBe('public');
});
});

View file

@ -15,41 +15,42 @@ import type { attachmentDomainV1 } from '../../../../common/types/domain';
/**
* @deprecated since version 8.1.0
*/
export const getAllCommentsRoute = createCasesRoute({
method: 'get',
path: CASE_COMMENTS_URL,
params: {
params: schema.object({
case_id: schema.string(),
}),
},
options: {
deprecated: true,
},
routerOptions: {
access: 'public',
summary: `Gets all case comments`,
tags: ['oas-tag:cases'],
// description: 'You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases with the comments you\'re seeking.',
// @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
deprecated: true,
},
handler: async ({ context, request, response }) => {
try {
const caseContext = await context.cases;
const client = await caseContext.getCasesClient();
const res: attachmentDomainV1.Attachments = await client.attachments.getAll({
caseID: request.params.case_id,
});
export const getAllCommentsRoute = ({ isServerless }: { isServerless?: boolean }) =>
createCasesRoute({
method: 'get',
path: CASE_COMMENTS_URL,
params: {
params: schema.object({
case_id: schema.string(),
}),
},
options: {
deprecated: true,
},
routerOptions: {
access: isServerless ? 'internal' : 'public',
summary: `Gets all case comments`,
tags: ['oas-tag:cases'],
// description: 'You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases with the comments you\'re seeking.',
// @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
deprecated: true,
},
handler: async ({ context, request, response }) => {
try {
const caseContext = await context.cases;
const client = await caseContext.getCasesClient();
const res: attachmentDomainV1.Attachments = await client.attachments.getAll({
caseID: request.params.case_id,
});
return response.ok({
body: res,
});
} catch (error) {
throw createCaseError({
message: `Failed to get all comments in route case id: ${request.params.case_id}: ${error}`,
error,
});
}
},
});
return response.ok({
body: res,
});
} catch (error) {
throw createCaseError({
message: `Failed to get all comments in route case id: ${request.params.case_id}: ${error}`,
error,
});
}
},
});

View file

@ -31,18 +31,18 @@ import { postCaseConfigureRoute } from './configure/post_configure';
import { getAllAlertsAttachedToCaseRoute } from './comments/get_alerts';
import { findUserActionsRoute } from './user_actions/find_user_actions';
export const getExternalRoutes = () =>
export const getExternalRoutes = ({ isServerless }: { isServerless?: boolean }) =>
[
deleteCaseRoute,
findCaseRoute,
getCaseRoute,
getCaseRoute({ isServerless }),
resolveCaseRoute,
patchCaseRoute,
postCaseRoute,
pushCaseRoute,
findUserActionsRoute,
getUserActionsRoute,
getStatusRoute,
getUserActionsRoute({ isServerless }),
getStatusRoute({ isServerless }),
getCasesByAlertIdRoute,
getReportersRoute,
getTagsRoute,
@ -50,7 +50,7 @@ export const getExternalRoutes = () =>
deleteAllCommentsRoute,
findCommentsRoute,
getCommentRoute,
getAllCommentsRoute,
getAllCommentsRoute({ isServerless }),
patchCommentRoute,
postCommentRoute,
getCaseConfigureRoute,

View file

@ -0,0 +1,22 @@
/*
* 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 { getStatusRoute } from './get_status';
describe('getStatusRoute', () => {
it('marks the endpoint internal in serverless', async () => {
const router = getStatusRoute({ isServerless: true });
expect(router.routerOptions?.access).toBe('internal');
});
it('marks the endpoint public in non-serverless', async () => {
const router = getStatusRoute({ isServerless: false });
expect(router.routerOptions?.access).toBe('public');
});
});

View file

@ -15,37 +15,38 @@ import type { statsApiV1 } from '../../../../common/types/api';
/**
* @deprecated since version 8.1.0
*/
export const getStatusRoute: CaseRoute = createCasesRoute({
method: 'get',
path: CASE_STATUS_URL,
options: { deprecated: true },
routerOptions: {
access: 'public',
summary: `Get case status summary`,
tags: ['oas-tag:cases'],
description:
'Returns the number of cases that are open, closed, and in progress in the default space.',
// You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.
// @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
deprecated: true,
},
handler: async ({ context, request, response }) => {
try {
const caseContext = await context.cases;
const client = await caseContext.getCasesClient();
export const getStatusRoute = ({ isServerless }: { isServerless?: boolean }): CaseRoute =>
createCasesRoute({
method: 'get',
path: CASE_STATUS_URL,
options: { deprecated: true },
routerOptions: {
access: isServerless ? 'internal' : 'public',
summary: `Get case status summary`,
tags: ['oas-tag:cases'],
description:
'Returns the number of cases that are open, closed, and in progress in the default space.',
// You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.
// @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
deprecated: true,
},
handler: async ({ context, request, response }) => {
try {
const caseContext = await context.cases;
const client = await caseContext.getCasesClient();
const res: statsApiV1.CasesStatusResponse = await client.metrics.getStatusTotalsByType(
request.query as statsApiV1.CasesStatusRequest
);
const res: statsApiV1.CasesStatusResponse = await client.metrics.getStatusTotalsByType(
request.query as statsApiV1.CasesStatusRequest
);
return response.ok({
body: res,
});
} catch (error) {
throw createCaseError({
message: `Failed to get status stats in route: ${error}`,
error,
});
}
},
});
return response.ok({
body: res,
});
} catch (error) {
throw createCaseError({
message: `Failed to get status stats in route: ${error}`,
error,
});
}
},
});

View file

@ -0,0 +1,22 @@
/*
* 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 { getUserActionsRoute } from './get_all_user_actions';
describe('getUserActionsRoute', () => {
it('marks the endpoint internal in serverless', async () => {
const router = getUserActionsRoute({ isServerless: true });
expect(router.routerOptions?.access).toBe('internal');
});
it('marks the endpoint public in non-serverless', async () => {
const router = getUserActionsRoute({ isServerless: false });
expect(router.routerOptions?.access).toBe('public');
});
});

View file

@ -15,41 +15,42 @@ import { createCasesRoute } from '../create_cases_route';
/**
* @deprecated since version 8.1.0
*/
export const getUserActionsRoute = createCasesRoute({
method: 'get',
path: CASE_USER_ACTIONS_URL,
params: {
params: schema.object({
case_id: schema.string(),
}),
},
options: { deprecated: true },
routerOptions: {
access: 'public',
summary: 'Get case activity',
description: `Returns all user activity for a case.`,
// You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're seeking.
tags: ['oas-tag:cases'],
// @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
deprecated: true,
},
handler: async ({ context, request, response }) => {
try {
const caseContext = await context.cases;
const casesClient = await caseContext.getCasesClient();
const caseId = request.params.case_id;
export const getUserActionsRoute = ({ isServerless }: { isServerless?: boolean }) =>
createCasesRoute({
method: 'get',
path: CASE_USER_ACTIONS_URL,
params: {
params: schema.object({
case_id: schema.string(),
}),
},
options: { deprecated: true },
routerOptions: {
access: isServerless ? 'internal' : 'public',
summary: 'Get case activity',
description: `Returns all user activity for a case.`,
// You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're seeking.
tags: ['oas-tag:cases'],
// @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
deprecated: true,
},
handler: async ({ context, request, response }) => {
try {
const caseContext = await context.cases;
const casesClient = await caseContext.getCasesClient();
const caseId = request.params.case_id;
const res: userActionApiV1.CaseUserActionsDeprecatedResponse =
await casesClient.userActions.getAll({ caseId });
const res: userActionApiV1.CaseUserActionsDeprecatedResponse =
await casesClient.userActions.getAll({ caseId });
return response.ok({
body: res,
});
} catch (error) {
throw createCaseError({
message: `Failed to retrieve case user actions in route case id: ${request.params.case_id}: ${error}`,
error,
});
}
},
});
return response.ok({
body: res,
});
} catch (error) {
throw createCaseError({
message: `Failed to retrieve case user actions in route case id: ${request.params.case_id}: ${error}`,
error,
});
}
},
});

View file

@ -460,7 +460,7 @@ export const getAllCasesStatuses = async ({
export const getCase = async ({
supertest,
caseId,
includeComments = false,
includeComments,
expectedHttpCode = 200,
auth = { user: superUser, space: null },
}: {
@ -470,10 +470,12 @@ export const getCase = async ({
expectedHttpCode?: number;
auth?: { user: User; space: string | null };
}): Promise<Case> => {
const basePath = `${getSpaceUrlPrefix(auth?.space)}${CASES_URL}/${caseId}`;
const path =
includeComments != null ? `${basePath}?includeComments=${includeComments}` : basePath;
const { body: theCase } = await supertest
.get(
`${getSpaceUrlPrefix(auth?.space)}${CASES_URL}/${caseId}?includeComments=${includeComments}`
)
.get(path)
.set('kbn-xsrf', 'true')
.set('x-elastic-internal-origin', 'foo')
.auth(auth.user.username, auth.user.password)

View file

@ -159,22 +159,22 @@ export function SvlCasesApiServiceProvider({ getService }: FtrProviderContext) {
{
caseId,
space = 'default',
includeComments = false,
expectedHttpCode = 200,
includeComments,
}: {
caseId: string;
space?: string;
includeComments?: boolean;
expectedHttpCode?: number;
includeComments?: boolean;
},
roleAuthc: RoleCredentials
): Promise<Case> {
const basePath = `${this.getSpaceUrlPrefix(space)}${CASES_URL}/${caseId}`;
const path =
includeComments != null ? `${basePath}?includeComments=${includeComments}` : basePath;
const { body: theCase } = await supertestWithoutAuth
.get(
`${this.getSpaceUrlPrefix(
space
)}${CASES_URL}/${caseId}?includeComments=${includeComments}`
)
.get(path)
.set(svlCommonApi.getInternalRequestHeader())
.set(roleAuthc.apiKeyHeader)
.expect(expectedHttpCode);

View file

@ -0,0 +1,45 @@
/*
* 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 { CASE_COMMENTS_URL } from '@kbn/cases-plugin/common/constants';
import type { RoleCredentials } from '../../../../shared/services';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext): void => {
const svlCases = getService('svlCases');
const svlUserManager = getService('svlUserManager');
const supertestWithoutAuth = getService('supertestWithoutAuth');
const svlCommonApi = getService('svlCommonApi');
describe('get_all_comments', () => {
let roleAuthc: RoleCredentials;
before(async () => {
roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin');
});
after(async () => {
await svlUserManager.invalidateM2mApiKeyWithRoleScope(roleAuthc);
});
afterEach(async () => {
await svlCases.api.deleteCases();
});
it('should fetch the status correctly with internal request headers', async () => {
await supertestWithoutAuth
.get(CASE_COMMENTS_URL)
.set(svlCommonApi.getInternalRequestHeader())
.set(roleAuthc.apiKeyHeader)
.expect(200);
});
it('should not fetch the status correctly with no internal request headers', async () => {
await supertestWithoutAuth.get(CASE_COMMENTS_URL).set(roleAuthc.apiKeyHeader).expect(400);
});
});
};

View file

@ -0,0 +1,45 @@
/*
* 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 { CASE_USER_ACTIONS_URL } from '@kbn/cases-plugin/common/constants';
import type { RoleCredentials } from '../../../../shared/services';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext): void => {
const svlCases = getService('svlCases');
const svlUserManager = getService('svlUserManager');
const supertestWithoutAuth = getService('supertestWithoutAuth');
const svlCommonApi = getService('svlCommonApi');
describe('get_all_user_actions', () => {
let roleAuthc: RoleCredentials;
before(async () => {
roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin');
});
after(async () => {
await svlUserManager.invalidateM2mApiKeyWithRoleScope(roleAuthc);
});
afterEach(async () => {
await svlCases.api.deleteCases();
});
it('should fetch the status correctly with internal request headers', async () => {
await supertestWithoutAuth
.get(CASE_USER_ACTIONS_URL)
.set(svlCommonApi.getInternalRequestHeader())
.set(roleAuthc.apiKeyHeader)
.expect(200);
});
it('should not fetch the status correctly with no internal request headers', async () => {
await supertestWithoutAuth.get(CASE_USER_ACTIONS_URL).set(roleAuthc.apiKeyHeader).expect(400);
});
});
};

View file

@ -36,7 +36,7 @@ export default ({ getService }: FtrProviderContext): void => {
const theCase = await svlCases.api.getCase(
{
caseId: postedCase.id,
includeComments: true,
expectedHttpCode: 200,
},
roleAuthc
);
@ -47,7 +47,22 @@ export default ({ getService }: FtrProviderContext): void => {
expect(data).to.eql(expectedData);
expect(createdBy).to.have.keys('full_name', 'email', 'username');
expect(data.comments?.length).to.eql(0);
});
it('should throw a 400 if the query param includeComments is being used', async () => {
const postedCase = await svlCases.api.createCase(
svlCases.api.getPostCaseRequest('observability'),
roleAuthc
);
await svlCases.api.getCase(
{
caseId: postedCase.id,
includeComments: true,
expectedHttpCode: 400,
},
roleAuthc
);
});
});
};

View file

@ -0,0 +1,45 @@
/*
* 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 { CASE_STATUS_URL } from '@kbn/cases-plugin/common/constants';
import type { RoleCredentials } from '../../../../shared/services';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext): void => {
const svlCases = getService('svlCases');
const svlUserManager = getService('svlUserManager');
const supertestWithoutAuth = getService('supertestWithoutAuth');
const svlCommonApi = getService('svlCommonApi');
describe('get_status', () => {
let roleAuthc: RoleCredentials;
before(async () => {
roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin');
});
after(async () => {
await svlUserManager.invalidateM2mApiKeyWithRoleScope(roleAuthc);
});
afterEach(async () => {
await svlCases.api.deleteCases();
});
it('should fetch the status correctly with internal request headers', async () => {
await supertestWithoutAuth
.get(CASE_STATUS_URL)
.set(svlCommonApi.getInternalRequestHeader())
.set(roleAuthc.apiKeyHeader)
.expect(200);
});
it('should not fetch the status correctly with no internal request headers', async () => {
await supertestWithoutAuth.get(CASE_STATUS_URL).set(roleAuthc.apiKeyHeader).expect(400);
});
});
};

View file

@ -12,5 +12,8 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./get_case'));
loadTestFile(require.resolve('./find_cases'));
loadTestFile(require.resolve('./post_case'));
loadTestFile(require.resolve('./get_status'));
loadTestFile(require.resolve('./get_all_comments'));
loadTestFile(require.resolve('./get_all_user_actions'));
});
}

View file

@ -31,7 +31,7 @@ export default ({ getService }: FtrProviderContext): void => {
const theCase = await svlCases.api.getCase(
{
caseId: postedCase.id,
includeComments: true,
expectedHttpCode: 200,
},
roleAuthc
);
@ -41,7 +41,22 @@ export default ({ getService }: FtrProviderContext): void => {
const { created_by: _, ...expectedData } = svlCases.api.postCaseResp('securitySolution');
expect(data).to.eql(expectedData);
expect(createdBy).to.have.keys('full_name', 'email', 'username');
expect(data.comments?.length).to.eql(0);
});
it('should throw a 400 if the query param includeComments is being used', async () => {
const postedCase = await svlCases.api.createCase(
svlCases.api.getPostCaseRequest('securitySolution'),
roleAuthc
);
await svlCases.api.getCase(
{
caseId: postedCase.id,
includeComments: true,
expectedHttpCode: 400,
},
roleAuthc
);
});
});
};