From 6442b11cffb5ac681581fe79f9b4bc21516c2731 Mon Sep 17 00:00:00 2001 From: Steph Milovic Date: Tue, 26 Jul 2022 12:12:16 -0600 Subject: [PATCH 1/8] tests and rm real url --- .../cases_webhook/api.test.ts | 8 +- .../cases_webhook/mock.ts | 4 +- .../cases_webhook/service.test.ts | 31 +- .../builtin_action_types/jira/api.test.ts | 8 +- .../server/builtin_action_types/jira/mocks.ts | 4 +- .../builtin_action_types/jira/service.test.ts | 71 ++-- .../server/lib/mustache_renderer.test.ts | 6 +- .../cypress/fixtures/7_16_case.ndjson | 4 +- .../security_solution/cypress/objects/case.ts | 41 ++- .../cases_webhook/webhook_connectors.test.tsx | 11 +- .../action_type_menu.test.tsx | 306 ++++++++++++------ .../create_connector_flyout/index.test.tsx | 29 ++ .../create_connector_flyout/index.tsx | 1 - .../builtin_action_types/cases_webhook.ts | 12 +- .../builtin_action_types/cases_webhook.ts | 12 +- 15 files changed, 331 insertions(+), 217 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/api.test.ts index 4764d9acdb235..8c0284f2245ad 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/api.test.ts @@ -31,7 +31,7 @@ describe('api', () => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', comments: [ { commentId: 'case-comment-1', @@ -57,7 +57,7 @@ describe('api', () => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }); }); @@ -109,7 +109,7 @@ describe('api', () => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', comments: [ { commentId: 'case-comment-1', @@ -135,7 +135,7 @@ describe('api', () => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/mock.ts b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/mock.ts index 20a5bcdfc1162..74627658cde81 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/mock.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/mock.ts @@ -24,7 +24,7 @@ const createMock = (): jest.Mocked => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }) ), updateIncident: jest.fn().mockImplementation(() => @@ -32,7 +32,7 @@ const createMock = (): jest.Mocked => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }) ), createComment: jest.fn(), diff --git a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.test.ts index cf8464d71d8a2..fadd84073e858 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.test.ts @@ -30,24 +30,23 @@ const configurationUtilities = actionsConfigMock.create(); const config: CasesWebhookPublicConfigurationType = { createCommentJson: '{"body":{{{case.comment}}}}', createCommentMethod: CasesWebhookMethods.POST, - createCommentUrl: - 'https://siem-kibana.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment', + createCommentUrl: 'https://coolsite.net/issue/{{{external.system.id}}}/comment', createIncidentJson: '{"fields":{"title":{{{case.title}}},"description":{{{case.description}}},"tags":{{{case.tags}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', createIncidentMethod: CasesWebhookMethods.POST, createIncidentResponseKey: 'id', - createIncidentUrl: 'https://siem-kibana.atlassian.net/rest/api/2/issue', + createIncidentUrl: 'https://coolsite.net/issue', getIncidentResponseCreatedDateKey: 'fields.created', getIncidentResponseExternalTitleKey: 'key', getIncidentResponseUpdatedDateKey: 'fields.updated', hasAuth: true, headers: { ['content-type']: 'application/json' }, - incidentViewUrl: 'https://siem-kibana.atlassian.net/browse/{{{external.system.title}}}', - getIncidentUrl: 'https://siem-kibana.atlassian.net/rest/api/2/issue/{{{external.system.id}}}', + incidentViewUrl: 'https://coolsite.net/browse/{{{external.system.title}}}', + getIncidentUrl: 'https://coolsite.net/issue/{{{external.system.id}}}', updateIncidentJson: '{"fields":{"title":{{{case.title}}},"description":{{{case.description}}},"tags":{{{case.tags}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', updateIncidentMethod: CasesWebhookMethods.PUT, - updateIncidentUrl: 'https://siem-kibana.atlassian.net/rest/api/2/issue/{{{external.system.id}}}', + updateIncidentUrl: 'https://coolsite.net/issue/{{{external.system.id}}}', }; const secrets = { user: 'user', @@ -154,7 +153,7 @@ describe('Cases webhook service', () => { await service.getIncident('1'); expect(requestMock).toHaveBeenCalledWith({ axios, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/1', + url: 'https://coolsite.net/issue/1', logger, configurationUtilities, }); @@ -231,7 +230,7 @@ describe('Cases webhook service', () => { title: 'CK-1', id: '1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }); }); @@ -260,7 +259,7 @@ describe('Cases webhook service', () => { expect(requestMock.mock.calls[0][0]).toEqual({ axios, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue', + url: 'https://coolsite.net/issue', logger, method: CasesWebhookMethods.POST, configurationUtilities, @@ -326,7 +325,7 @@ describe('Cases webhook service', () => { title: 'CK-1', id: '1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }); }); @@ -348,7 +347,7 @@ describe('Cases webhook service', () => { logger, method: CasesWebhookMethods.PUT, configurationUtilities, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/1', + url: 'https://coolsite.net/issue/1', data: JSON.stringify({ fields: { title: 'title', @@ -426,7 +425,7 @@ describe('Cases webhook service', () => { logger, method: CasesWebhookMethods.POST, configurationUtilities, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/1/comment', + url: 'https://coolsite.net/issue/1/comment', data: `{"body":"comment"}`, }); }); @@ -664,7 +663,7 @@ describe('Cases webhook service', () => { test('getIncident- escapes url', async () => { await service.getIncident('../../malicious-app/malicious-endpoint/'); expect(requestMock.mock.calls[0][0].url).toEqual( - 'https://siem-kibana.atlassian.net/rest/api/2/issue/..%2F..%2Fmalicious-app%2Fmalicious-endpoint%2F' + 'https://coolsite.net/issue/..%2F..%2Fmalicious-app%2Fmalicious-endpoint%2F' ); }); @@ -681,7 +680,7 @@ describe('Cases webhook service', () => { }; const res = await service.createIncident(incident); expect(res.url).toEqual( - 'https://siem-kibana.atlassian.net/browse/..%2F..%2Fmalicious-app%2Fmalicious-endpoint%2F' + 'https://coolsite.net/browse/..%2F..%2Fmalicious-app%2Fmalicious-endpoint%2F' ); }); @@ -700,7 +699,7 @@ describe('Cases webhook service', () => { await service.updateIncident(incident); expect(requestMock.mock.calls[0][0].url).toEqual( - 'https://siem-kibana.atlassian.net/rest/api/2/issue/..%2F..%2Fmalicious-app%2Fmalicious-endpoint%2F' + 'https://coolsite.net/issue/..%2F..%2Fmalicious-app%2Fmalicious-endpoint%2F' ); }); test('createComment- escapes url', async () => { @@ -714,7 +713,7 @@ describe('Cases webhook service', () => { await service.createComment(commentReq); expect(requestMock.mock.calls[0][0].url).toEqual( - 'https://siem-kibana.atlassian.net/rest/api/2/issue/..%2F..%2Fmalicious-app%2Fmalicious-endpoint%2F/comment' + 'https://coolsite.net/issue/..%2F..%2Fmalicious-app%2Fmalicious-endpoint%2F/comment' ); }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/api.test.ts index b682d069397b8..43b969f9c9681 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/api.test.ts @@ -31,7 +31,7 @@ describe('api', () => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', comments: [ { commentId: 'case-comment-1', @@ -57,7 +57,7 @@ describe('api', () => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }); }); @@ -150,7 +150,7 @@ describe('api', () => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', comments: [ { commentId: 'case-comment-1', @@ -176,7 +176,7 @@ describe('api', () => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts index 225fb7c364d3a..f006fdabdc912 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts @@ -24,7 +24,7 @@ const createMock = (): jest.Mocked => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }) ), updateIncident: jest.fn().mockImplementation(() => @@ -32,7 +32,7 @@ const createMock = (): jest.Mocked => { id: 'incident-1', title: 'CK-1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }) ), createComment: jest.fn(), diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts index c62a1f3230e64..a60dd11af4707 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts @@ -114,9 +114,8 @@ const mockNewAPI = () => data: { capabilities: { 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', - 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + 'https://coolsite.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': 'https://coolsite.net/rest/capabilities/list-issuetype-fields', }, }, }) @@ -127,7 +126,7 @@ const mockOldAPI = () => createAxiosResponse({ data: { capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + navigation: 'https://coolsite.net/rest/capabilities/navigation', }, }, }) @@ -141,7 +140,7 @@ describe('Jira service', () => { { // The trailing slash at the end of the url is intended. // All API calls need to have the trailing slash removed. - config: { apiUrl: 'https://siem-kibana.atlassian.net/', projectKey: 'CK' }, + config: { apiUrl: 'https://coolsite.net/', projectKey: 'CK' }, secrets: { apiToken: 'token', email: 'elastic@elastic.com' }, }, logger, @@ -240,7 +239,7 @@ describe('Jira service', () => { await service.getIncident('1'); expect(requestMock).toHaveBeenCalledWith({ axios, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/1', + url: 'https://coolsite.net/rest/api/2/issue/1', logger, configurationUtilities, }); @@ -313,7 +312,7 @@ describe('Jira service', () => { title: 'CK-1', id: '1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }); }); @@ -329,7 +328,7 @@ describe('Jira service', () => { createAxiosResponse({ data: { capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + navigation: 'https://coolsite.net/rest/capabilities/navigation', }, }, }) @@ -365,12 +364,12 @@ describe('Jira service', () => { title: 'CK-1', id: '1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }); expect(requestMock).toHaveBeenCalledWith({ axios, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue', + url: 'https://coolsite.net/rest/api/2/issue', logger, method: 'post', configurationUtilities, @@ -392,7 +391,7 @@ describe('Jira service', () => { createAxiosResponse({ data: { capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + navigation: 'https://coolsite.net/rest/capabilities/navigation', }, }, }) @@ -427,7 +426,7 @@ describe('Jira service', () => { expect(requestMock).toHaveBeenCalledWith({ axios, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue', + url: 'https://coolsite.net/rest/api/2/issue', logger, method: 'post', configurationUtilities, @@ -459,7 +458,7 @@ describe('Jira service', () => { expect(requestMock).toHaveBeenCalledWith({ axios, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue', + url: 'https://coolsite.net/rest/api/2/issue', logger, method: 'post', configurationUtilities, @@ -538,7 +537,7 @@ describe('Jira service', () => { title: 'CK-1', id: '1', pushedDate: '2020-04-27T10:59:46.202Z', - url: 'https://siem-kibana.atlassian.net/browse/CK-1', + url: 'https://coolsite.net/browse/CK-1', }); }); @@ -560,7 +559,7 @@ describe('Jira service', () => { logger, method: 'put', configurationUtilities, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/1', + url: 'https://coolsite.net/rest/api/2/issue/1', data: { fields: { summary: 'title', @@ -644,7 +643,7 @@ describe('Jira service', () => { logger, method: 'post', configurationUtilities, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/1/comment', + url: 'https://coolsite.net/rest/api/2/issue/1/comment', data: { body: 'comment' }, }); }); @@ -686,7 +685,7 @@ describe('Jira service', () => { const res = await service.getCapabilities(); expect(res).toEqual({ capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + navigation: 'https://coolsite.net/rest/capabilities/navigation', }, }); }); @@ -701,7 +700,7 @@ describe('Jira service', () => { logger, method: 'get', configurationUtilities, - url: 'https://siem-kibana.atlassian.net/rest/capabilities', + url: 'https://coolsite.net/rest/capabilities', }); }); @@ -782,7 +781,7 @@ describe('Jira service', () => { logger, method: 'get', configurationUtilities, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta?projectKeys=CK&expand=projects.issuetypes.fields', + url: 'https://coolsite.net/rest/api/2/issue/createmeta?projectKeys=CK&expand=projects.issuetypes.fields', }); }); @@ -856,7 +855,7 @@ describe('Jira service', () => { logger, method: 'get', configurationUtilities, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta/CK/issuetypes', + url: 'https://coolsite.net/rest/api/2/issue/createmeta/CK/issuetypes', }); }); @@ -931,7 +930,7 @@ describe('Jira service', () => { logger, method: 'get', configurationUtilities, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta?projectKeys=CK&issuetypeIds=10006&expand=projects.issuetypes.fields', + url: 'https://coolsite.net/rest/api/2/issue/createmeta?projectKeys=CK&issuetypeIds=10006&expand=projects.issuetypes.fields', }); }); @@ -1044,7 +1043,7 @@ describe('Jira service', () => { logger, method: 'get', configurationUtilities, - url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta/CK/issuetypes/10006', + url: 'https://coolsite.net/rest/api/2/issue/createmeta/CK/issuetypes/10006', }); }); @@ -1112,7 +1111,7 @@ describe('Jira service', () => { logger, method: 'get', configurationUtilities, - url: `https://siem-kibana.atlassian.net/rest/api/2/search?jql=project%3D%22CK%22%20and%20summary%20~%22Test%20title%22`, + url: `https://coolsite.net/rest/api/2/search?jql=project%3D%22CK%22%20and%20summary%20~%22Test%20title%22`, }); }); @@ -1171,7 +1170,7 @@ describe('Jira service', () => { logger, method: 'get', configurationUtilities, - url: `https://siem-kibana.atlassian.net/rest/api/2/issue/RJ-107`, + url: `https://coolsite.net/rest/api/2/issue/RJ-107`, }); }); @@ -1206,9 +1205,9 @@ describe('Jira service', () => { data: { capabilities: { 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'https://coolsite.net/rest/capabilities/list-project-issuetypes', 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + 'https://coolsite.net/rest/capabilities/list-issuetype-fields', }, }, }) @@ -1225,9 +1224,9 @@ describe('Jira service', () => { data: { capabilities: { 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'https://coolsite.net/rest/capabilities/list-project-issuetypes', 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + 'https://coolsite.net/rest/capabilities/list-issuetype-fields', }, }, }) @@ -1237,9 +1236,9 @@ describe('Jira service', () => { data: { capabilities: { 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'https://coolsite.net/rest/capabilities/list-project-issuetypes', 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + 'https://coolsite.net/rest/capabilities/list-issuetype-fields', }, }, }) @@ -1289,12 +1288,12 @@ describe('Jira service', () => { callMocks(); await service.getFields(); const callUrls = [ - 'https://siem-kibana.atlassian.net/rest/capabilities', - 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta/CK/issuetypes', - 'https://siem-kibana.atlassian.net/rest/capabilities', - 'https://siem-kibana.atlassian.net/rest/capabilities', - 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta/CK/issuetypes/10006', - 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta/CK/issuetypes/10007', + 'https://coolsite.net/rest/capabilities', + 'https://coolsite.net/rest/api/2/issue/createmeta/CK/issuetypes', + 'https://coolsite.net/rest/capabilities', + 'https://coolsite.net/rest/capabilities', + 'https://coolsite.net/rest/api/2/issue/createmeta/CK/issuetypes/10006', + 'https://coolsite.net/rest/api/2/issue/createmeta/CK/issuetypes/10007', ]; requestMock.mock.calls.forEach((call, i) => { expect(call[0].url).toEqual(callUrls[i]); diff --git a/x-pack/plugins/actions/server/lib/mustache_renderer.test.ts b/x-pack/plugins/actions/server/lib/mustache_renderer.test.ts index 154937c6f8065..4fa76f5a133ca 100644 --- a/x-pack/plugins/actions/server/lib/mustache_renderer.test.ts +++ b/x-pack/plugins/actions/server/lib/mustache_renderer.test.ts @@ -131,7 +131,7 @@ describe('mustache_renderer', () => { const summary = 'A cool good summary'; const description = 'A cool good description'; const tags = ['cool', 'neat', 'nice']; - const str = 'https://siem-kibana.atlassian.net/browse/{{{external.system.title}}}'; + const str = 'https://coolsite.net/browse/{{{external.system.title}}}'; const objStr = '{\n' + @@ -177,7 +177,7 @@ describe('mustache_renderer', () => { }, }; expect(renderMustacheStringNoEscape(str, urlVariables)).toBe( - `https://siem-kibana.atlassian.net/browse/cool_title` + `https://coolsite.net/browse/cool_title` ); }); it('Inserts variables into url with quotes whens stringified', () => { @@ -190,7 +190,7 @@ describe('mustache_renderer', () => { }, }; expect(renderMustacheStringNoEscape(str, urlVariablesStr)).toBe( - `https://siem-kibana.atlassian.net/browse/"cool_title"` + `https://coolsite.net/browse/"cool_title"` ); }); it('Inserts variables into JSON non-escaped when triple brackets and JSON.stringified variables', () => { diff --git a/x-pack/plugins/security_solution/cypress/fixtures/7_16_case.ndjson b/x-pack/plugins/security_solution/cypress/fixtures/7_16_case.ndjson index bd7b082020279..12285fa7671aa 100644 --- a/x-pack/plugins/security_solution/cypress/fixtures/7_16_case.ndjson +++ b/x-pack/plugins/security_solution/cypress/fixtures/7_16_case.ndjson @@ -1,4 +1,4 @@ -{"attributes":{"actionTypeId":".jira","config":{"apiUrl":"https://siem-kibana.atlassian.net/","projectKey":"CASES"},"isMissingSecrets":true,"name":"Jira test"},"coreMigrationVersion":"7.16.0","id":"018d0110-46d1-11ec-a89e-8339c89698d8","migrationVersion":{"action":"7.16.0"},"references":[],"type":"action","updated_at":"2021-11-16T11:33:22.994Z","version":"WzIwNjYsMV0="} +{"attributes":{"actionTypeId":".jira","config":{"apiUrl":"https://coolsite.net/","projectKey":"CASES"},"isMissingSecrets":true,"name":"Jira test"},"coreMigrationVersion":"7.16.0","id":"018d0110-46d1-11ec-a89e-8339c89698d8","migrationVersion":{"action":"7.16.0"},"references":[],"type":"action","updated_at":"2021-11-16T11:33:22.994Z","version":"WzIwNjYsMV0="} {"attributes":{"closed_at":null,"closed_by":null,"connector":{"fields":[{"key":"issueType","value":"10001"},{"key":"parent","value":null},{"key":"priority","value":null}],"name":"Jira test","type":".jira"},"created_at":"2021-11-16T11:21:19.242Z","created_by":{"email":null,"full_name":"glo@test.co","username":"glo"},"description":"This is the description of the 7.16 case that I'm going to import in future versions.","external_service":null,"owner":"securitySolution","settings":{"syncAlerts":false},"status":"in-progress","tags":["export case"],"title":"7.16 case to export","type":"individual","updated_at":"2021-11-16T11:33:44.787Z","updated_by":{"email":"","full_name":"","username":"test"}},"coreMigrationVersion":"7.16.0","id":"5228e870-46cf-11ec-a89e-8339c89698d8","migrationVersion":{"cases":"7.15.0"},"references":[{"id":"018d0110-46d1-11ec-a89e-8339c89698d8","name":"connectorId","type":"action"}],"type":"cases","updated_at":"2021-11-16T11:33:44.788Z","version":"WzIwNzMsMV0="} {"attributes":{"action":"update","action_at":"2021-11-16T11:33:44.787Z","action_by":{"email":"","full_name":"","username":"test"},"action_field":["connector"],"new_value":"{\"name\":\"Jira test\",\"type\":\".jira\",\"fields\":{\"issueType\":\"10001\",\"parent\":null,\"priority\":null}}","old_value":"{\"name\":\"none\",\"type\":\".none\",\"fields\":null}","owner":"securitySolution"},"coreMigrationVersion":"7.16.0","id":"0ef96fa0-46d1-11ec-a89e-8339c89698d8","migrationVersion":{"cases-user-actions":"7.16.0"},"references":[{"id":"5228e870-46cf-11ec-a89e-8339c89698d8","name":"associated-cases","type":"cases"},{"id":"018d0110-46d1-11ec-a89e-8339c89698d8","name":"connectorId","type":"action"}],"score":null,"sort":[1637062424787,4305],"type":"cases-user-actions","updated_at":"2021-11-16T11:33:45.498Z","version":"WzIwNzQsMV0="} {"attributes":{"action":"create","action_at":"2021-11-16T11:21:19.242Z","action_by":{"email":null,"full_name":"glo@test.co","username":"glo"},"action_field":["description","status","tags","title","connector","settings","owner"],"new_value":"{\"type\":\"individual\",\"title\":\"7.16 case to export\",\"tags\":[\"export case\"],\"description\":\"This is the description of the 7.16 case that I'm going to import in future versions.\",\"connector\":{\"name\":\"none\",\"type\":\".none\",\"fields\":null},\"settings\":{\"syncAlerts\":false},\"owner\":\"securitySolution\"}","old_value":null,"owner":"securitySolution"},"coreMigrationVersion":"7.16.0","id":"52b87e40-46cf-11ec-a89e-8339c89698d8","migrationVersion":{"cases-user-actions":"7.16.0"},"references":[{"id":"5228e870-46cf-11ec-a89e-8339c89698d8","name":"associated-cases","type":"cases"}],"score":null,"sort":[1637061679242,4228],"type":"cases-user-actions","updated_at":"2021-11-16T11:21:20.164Z","version":"WzE5MjMsMV0="} @@ -12,4 +12,4 @@ {"attributes":{"action":"create","action_at":"2021-11-16T11:24:09.128Z","action_by":{"email":null,"full_name":"glo@test.co","username":"glo"},"action_field":["comment"],"new_value":"{\"comment\":\"!{lens{\\\"timeRange\\\":{\\\"from\\\":\\\"now-7d\\\",\\\"to\\\":\\\"now\\\",\\\"mode\\\":\\\"relative\\\"},\\\"attributes\\\":{\\\"title\\\":\\\"\\\",\\\"description\\\":\\\"Events acknowledged by the output (includes events dropped by the output). (From beat.stats.libbeat.output.events.acked)\\\",\\\"visualizationType\\\":\\\"lnsXY\\\",\\\"type\\\":\\\"lens\\\",\\\"references\\\":[{\\\"type\\\":\\\"index-pattern\\\",\\\"id\\\":\\\"92888d80-46cf-11ec-a89e-8339c89698d8\\\",\\\"name\\\":\\\"indexpattern-datasource-current-indexpattern\\\"},{\\\"type\\\":\\\"index-pattern\\\",\\\"id\\\":\\\"92888d80-46cf-11ec-a89e-8339c89698d8\\\",\\\"name\\\":\\\"indexpattern-datasource-layer-03c31209-08e8-4917-b7d5-9d77ecf40dd1\\\"}],\\\"state\\\":{\\\"visualization\\\":{\\\"legend\\\":{\\\"isVisible\\\":true,\\\"position\\\":\\\"right\\\"},\\\"valueLabels\\\":\\\"hide\\\",\\\"fittingFunction\\\":\\\"None\\\",\\\"yLeftExtent\\\":{\\\"mode\\\":\\\"full\\\"},\\\"yRightExtent\\\":{\\\"mode\\\":\\\"full\\\"},\\\"axisTitlesVisibilitySettings\\\":{\\\"x\\\":true,\\\"yRight\\\":true,\\\"yLeft\\\":true},\\\"tickLabelsVisibilitySettings\\\":{\\\"x\\\":true,\\\"yRight\\\":true,\\\"yLeft\\\":true},\\\"labelsOrientation\\\":{\\\"x\\\":0,\\\"yRight\\\":0,\\\"yLeft\\\":0},\\\"gridlinesVisibilitySettings\\\":{\\\"x\\\":true,\\\"yRight\\\":true,\\\"yLeft\\\":true},\\\"preferredSeriesType\\\":\\\"line\\\",\\\"layers\\\":[{\\\"layerId\\\":\\\"03c31209-08e8-4917-b7d5-9d77ecf40dd1\\\",\\\"seriesType\\\":\\\"line\\\",\\\"xAccessor\\\":\\\"bd01502a-3d64-470e-8277-928d6a9399e2\\\",\\\"accessors\\\":[\\\"97dfd130-3c4d-477a-8e24-adc95b5a5e86\\\"],\\\"layerType\\\":\\\"data\\\"}]},\\\"query\\\":{\\\"query\\\":\\\"\\\",\\\"language\\\":\\\"kuery\\\"},\\\"filters\\\":[],\\\"datasourceStates\\\":{\\\"indexpattern\\\":{\\\"layers\\\":{\\\"03c31209-08e8-4917-b7d5-9d77ecf40dd1\\\":{\\\"columns\\\":{\\\"bd01502a-3d64-470e-8277-928d6a9399e2\\\":{\\\"label\\\":\\\"@timestamp\\\",\\\"dataType\\\":\\\"date\\\",\\\"operationType\\\":\\\"date_histogram\\\",\\\"sourceField\\\":\\\"@timestamp\\\",\\\"isBucketed\\\":true,\\\"scale\\\":\\\"interval\\\",\\\"params\\\":{\\\"interval\\\":\\\"auto\\\"}},\\\"97dfd130-3c4d-477a-8e24-adc95b5a5e86\\\":{\\\"label\\\":\\\"Count of records\\\",\\\"dataType\\\":\\\"number\\\",\\\"operationType\\\":\\\"count\\\",\\\"isBucketed\\\":false,\\\"scale\\\":\\\"ratio\\\",\\\"sourceField\\\":\\\"Records\\\"}},\\\"columnOrder\\\":[\\\"bd01502a-3d64-470e-8277-928d6a9399e2\\\",\\\"97dfd130-3c4d-477a-8e24-adc95b5a5e86\\\"],\\\"incompleteColumns\\\":{}}}}}}}}}\",\"type\":\"user\",\"owner\":\"securitySolution\"}","old_value":null,"owner":"securitySolution"},"coreMigrationVersion":"7.16.0","id":"b8076630-46cf-11ec-a89e-8339c89698d8","migrationVersion":{"cases-user-actions":"7.16.0"},"references":[{"id":"5228e870-46cf-11ec-a89e-8339c89698d8","name":"associated-cases","type":"cases"},{"id":"b76d4910-46cf-11ec-a89e-8339c89698d8","name":"associated-cases-comments","type":"cases-comments"}],"score":null,"sort":[1637061849128,4260],"type":"cases-user-actions","updated_at":"2021-11-16T11:24:10.131Z","version":"WzE5ODcsMV0="} {"attributes":{"alertId":"f339b9b0e9763b98bcdb7c4a65a10701aaa97a99e232cfd2dab2d8680f7c6c3a","associationType":"case","created_at":"2021-11-16T11:24:42.043Z","created_by":{"email":null,"full_name":"glo@test.co","username":"glo"},"index":".siem-signals-default-000001","owner":"securitySolution","pushed_at":null,"pushed_by":null,"rule":{"id":"f45fd050-46ce-11ec-a89e-8339c89698d8","name":"This is a test"},"type":"alert","updated_at":null,"updated_by":null},"coreMigrationVersion":"7.16.0","id":"cb0acce0-46cf-11ec-a89e-8339c89698d8","migrationVersion":{"cases-comments":"7.16.0"},"references":[{"id":"5228e870-46cf-11ec-a89e-8339c89698d8","name":"associated-cases","type":"cases"}],"score":null,"sort":[1637061882043,6107],"type":"cases-comments","updated_at":"2021-11-16T11:24:42.048Z","version":"WzE5OTYsMV0="} {"attributes":{"action":"create","action_at":"2021-11-16T11:24:42.043Z","action_by":{"email":null,"full_name":"glo@test.co","username":"glo"},"action_field":["comment"],"new_value":"{\"type\":\"alert\",\"alertId\":\"f339b9b0e9763b98bcdb7c4a65a10701aaa97a99e232cfd2dab2d8680f7c6c3a\",\"index\":\".siem-signals-default-000001\",\"rule\":{\"id\":\"f45fd050-46ce-11ec-a89e-8339c89698d8\",\"name\":\"This is a test\"},\"owner\":\"securitySolution\"}","old_value":null,"owner":"securitySolution"},"coreMigrationVersion":"7.16.0","id":"cb634d20-46cf-11ec-a89e-8339c89698d8","migrationVersion":{"cases-user-actions":"7.16.0"},"references":[{"id":"5228e870-46cf-11ec-a89e-8339c89698d8","name":"associated-cases","type":"cases"},{"id":"cb0acce0-46cf-11ec-a89e-8339c89698d8","name":"associated-cases-comments","type":"cases-comments"}],"score":null,"sort":[1637061882043,4263],"type":"cases-user-actions","updated_at":"2021-11-16T11:24:42.610Z","version":"WzE5OTgsMV0="} -{"excludedObjects":[],"excludedObjectsCount":0,"exportedCount":14,"missingRefCount":0,"missingReferences":[]} \ No newline at end of file +{"excludedObjects":[],"excludedObjectsCount":0,"exportedCount":14,"missingRefCount":0,"missingReferences":[]} diff --git a/x-pack/plugins/security_solution/cypress/objects/case.ts b/x-pack/plugins/security_solution/cypress/objects/case.ts index f174c80874240..ad29a8a415724 100644 --- a/x-pack/plugins/security_solution/cypress/objects/case.ts +++ b/x-pack/plugins/security_solution/cypress/objects/case.ts @@ -106,7 +106,7 @@ export const getMockConnectorsResponse = () => [ actionTypeId: '.jira', name: 'Jira', config: { - apiUrl: 'https://siem-kibana.atlassian.net', + apiUrl: 'https://coolsite.net', projectKey: 'RJ', }, isPreconfigured: false, @@ -235,11 +235,11 @@ export const getExecuteResponses = () => ({ issuetype: { allowedValues: [ { - self: 'https://siem-kibana.atlassian.net/rest/api/2/issuetype/10006', + self: 'https://coolsite.net/rest/api/2/issuetype/10006', id: '10006', description: 'A small, distinct piece of work.', iconUrl: - 'https://siem-kibana.atlassian.net/secure/viewavatar?size=medium&avatarId=10318&avatarType=issuetype', + 'https://coolsite.net/secure/viewavatar?size=medium&avatarId=10318&avatarType=issuetype', name: 'Task', subtask: false, avatarId: 10318, @@ -253,21 +253,20 @@ export const getExecuteResponses = () => ({ project: { allowedValues: [ { - self: 'https://siem-kibana.atlassian.net/rest/api/2/project/10011', + self: 'https://coolsite.net/rest/api/2/project/10011', id: '10011', key: 'RJ', name: 'Refactor Jira', projectTypeKey: 'business', simplified: false, avatarUrls: { - '48x48': - 'https://siem-kibana.atlassian.net/secure/projectavatar?pid=10011&avatarId=10423', + '48x48': 'https://coolsite.net/secure/projectavatar?pid=10011&avatarId=10423', '24x24': - 'https://siem-kibana.atlassian.net/secure/projectavatar?size=small&s=small&pid=10011&avatarId=10423', + 'https://coolsite.net/secure/projectavatar?size=small&s=small&pid=10011&avatarId=10423', '16x16': - 'https://siem-kibana.atlassian.net/secure/projectavatar?size=xsmall&s=xsmall&pid=10011&avatarId=10423', + 'https://coolsite.net/secure/projectavatar?size=xsmall&s=xsmall&pid=10011&avatarId=10423', '32x32': - 'https://siem-kibana.atlassian.net/secure/projectavatar?size=medium&s=medium&pid=10011&avatarId=10423', + 'https://coolsite.net/secure/projectavatar?size=medium&s=medium&pid=10011&avatarId=10423', }, }, ], @@ -277,39 +276,39 @@ export const getExecuteResponses = () => ({ priority: { allowedValues: [ { - self: 'https://siem-kibana.atlassian.net/rest/api/2/priority/1', - iconUrl: 'https://siem-kibana.atlassian.net/images/icons/priorities/highest.svg', + self: 'https://coolsite.net/rest/api/2/priority/1', + iconUrl: 'https://coolsite.net/images/icons/priorities/highest.svg', name: 'Highest', id: '1', }, { - self: 'https://siem-kibana.atlassian.net/rest/api/2/priority/2', - iconUrl: 'https://siem-kibana.atlassian.net/images/icons/priorities/high.svg', + self: 'https://coolsite.net/rest/api/2/priority/2', + iconUrl: 'https://coolsite.net/images/icons/priorities/high.svg', name: 'High', id: '2', }, { - self: 'https://siem-kibana.atlassian.net/rest/api/2/priority/3', - iconUrl: 'https://siem-kibana.atlassian.net/images/icons/priorities/medium.svg', + self: 'https://coolsite.net/rest/api/2/priority/3', + iconUrl: 'https://coolsite.net/images/icons/priorities/medium.svg', name: 'Medium', id: '3', }, { - self: 'https://siem-kibana.atlassian.net/rest/api/2/priority/4', - iconUrl: 'https://siem-kibana.atlassian.net/images/icons/priorities/low.svg', + self: 'https://coolsite.net/rest/api/2/priority/4', + iconUrl: 'https://coolsite.net/images/icons/priorities/low.svg', name: 'Low', id: '4', }, { - self: 'https://siem-kibana.atlassian.net/rest/api/2/priority/5', - iconUrl: 'https://siem-kibana.atlassian.net/images/icons/priorities/lowest.svg', + self: 'https://coolsite.net/rest/api/2/priority/5', + iconUrl: 'https://coolsite.net/images/icons/priorities/lowest.svg', name: 'Lowest', id: '5', }, ], defaultValue: { - self: 'https://siem-kibana.atlassian.net/rest/api/2/priority/3', - iconUrl: 'https://siem-kibana.atlassian.net/images/icons/priorities/medium.svg', + self: 'https://coolsite.net/rest/api/2/priority/3', + iconUrl: 'https://coolsite.net/images/icons/priorities/medium.svg', name: 'Medium', id: '3', }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.test.tsx index 3ce481f3b3466..320759095e36b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.test.tsx @@ -41,24 +41,23 @@ const invalidJsonBoth = `{"fields":{"summary":"wrong","description":"wrong","pro const config = { createCommentJson: '{"body":{{{case.comment}}}}', createCommentMethod: 'post', - createCommentUrl: - 'https://siem-kibana.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment', + createCommentUrl: 'https://coolsite.net/rest/api/2/issue/{{{external.system.id}}}/comment', createIncidentJson: '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', createIncidentMethod: 'post', createIncidentResponseKey: 'id', - createIncidentUrl: 'https://siem-kibana.atlassian.net/rest/api/2/issue', + createIncidentUrl: 'https://coolsite.net/rest/api/2/issue', getIncidentResponseCreatedDateKey: 'fields.created', getIncidentResponseExternalTitleKey: 'key', getIncidentResponseUpdatedDateKey: 'fields.updated', hasAuth: true, headers: [{ key: 'content-type', value: 'text' }], - incidentViewUrl: 'https://siem-kibana.atlassian.net/browse/{{{external.system.title}}}', - getIncidentUrl: 'https://siem-kibana.atlassian.net/rest/api/2/issue/{{{external.system.id}}}', + incidentViewUrl: 'https://coolsite.net/browse/{{{external.system.title}}}', + getIncidentUrl: 'https://coolsite.net/rest/api/2/issue/{{{external.system.id}}}', updateIncidentJson: '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', updateIncidentMethod: 'put', - updateIncidentUrl: 'https://siem-kibana.atlassian.net/rest/api/2/issue/{{{external.system.id}}}', + updateIncidentUrl: 'https://coolsite.net/rest/api/2/issue/{{{external.system.id}}}', }; const actionConnector = { secrets: { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx index df3101d11e5f8..702ee340d57f8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx @@ -41,121 +41,215 @@ describe('connector_add_flyout', () => { }, }; }); + afterEach(() => { + actionTypeRegistry.get.mockReset(); + jest.clearAllMocks(); + }); - it('renders action type menu with proper EuiCards for registered action types', async () => { - const onActionTypeChange = jest.fn(); - const actionType = actionTypeRegistryMock.createMockActionTypeModel({ - id: 'my-action-type', - iconClass: 'test', - selectMessage: 'test', - validateParams: (): Promise> => { - const validationResult = { errors: {} }; - return Promise.resolve(validationResult); - }, - actionConnectorFields: null, - }); - actionTypeRegistry.get.mockReturnValueOnce(actionType); - loadActionTypes.mockResolvedValueOnce([ - { - id: actionType.id, - enabled: true, - name: 'Test', - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'basic', - supportedFeatureIds: ['alerting'], - }, - ]); - - const wrapper = mountWithIntl( - - ); - await act(async () => { - await nextTick(); - wrapper.update(); - }); + describe('rendering', () => { + it('renders action type menu with proper EuiCards for registered action types', async () => { + const onActionTypeChange = jest.fn(); + const actionType = actionTypeRegistryMock.createMockActionTypeModel({ + id: 'my-action-type', + iconClass: 'test', + selectMessage: 'test', + validateParams: (): Promise> => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + }); + actionTypeRegistry.get.mockReturnValueOnce(actionType); + loadActionTypes.mockResolvedValueOnce([ + { + id: actionType.id, + enabled: true, + name: 'Test', + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + }, + ]); - expect(wrapper.find('[data-test-subj="my-action-type-card"]').exists()).toBeTruthy(); - }); + const wrapper = mountWithIntl( + + ); + await act(async () => { + await nextTick(); + wrapper.update(); + }); - it(`doesn't renders action types that are disabled via config`, async () => { - const onActionTypeChange = jest.fn(); - const actionType = actionTypeRegistryMock.createMockActionTypeModel({ - id: 'my-action-type', - iconClass: 'test', - selectMessage: 'test', - validateParams: (): Promise> => { - const validationResult = { errors: {} }; - return Promise.resolve(validationResult); - }, - actionConnectorFields: null, + expect(wrapper.find('[data-test-subj="my-action-type-card"]').exists()).toBeTruthy(); }); - actionTypeRegistry.get.mockReturnValueOnce(actionType); - loadActionTypes.mockResolvedValueOnce([ - { - id: actionType.id, - enabled: false, - name: 'Test', - enabledInConfig: false, - enabledInLicense: true, - minimumLicenseRequired: 'gold', - supportedFeatureIds: ['alerting'], - }, - ]); - - const wrapper = mountWithIntl( - - ); - await act(async () => { - await nextTick(); - wrapper.update(); + + it(`doesn't renders action types that are disabled via config`, async () => { + const onActionTypeChange = jest.fn(); + const actionType = actionTypeRegistryMock.createMockActionTypeModel({ + id: 'my-action-type', + iconClass: 'test', + selectMessage: 'test', + validateParams: (): Promise> => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + }); + actionTypeRegistry.get.mockReturnValueOnce(actionType); + loadActionTypes.mockResolvedValueOnce([ + { + id: actionType.id, + enabled: false, + name: 'Test', + enabledInConfig: false, + enabledInLicense: true, + minimumLicenseRequired: 'gold', + supportedFeatureIds: ['alerting'], + }, + ]); + + const wrapper = mountWithIntl( + + ); + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find('[data-test-subj="my-action-type-card"]').exists()).toBeFalsy(); }); - expect(wrapper.find('[data-test-subj="my-action-type-card"]').exists()).toBeFalsy(); - }); + it(`renders action types as disabled when disabled by license`, async () => { + const onActionTypeChange = jest.fn(); + const actionType = actionTypeRegistryMock.createMockActionTypeModel({ + id: 'my-action-type', + iconClass: 'test', + selectMessage: 'test', + validateParams: (): Promise> => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + }); + actionTypeRegistry.get.mockReturnValueOnce(actionType); + loadActionTypes.mockResolvedValueOnce([ + { + id: actionType.id, + enabled: false, + name: 'Test', + enabledInConfig: true, + enabledInLicense: false, + minimumLicenseRequired: 'gold', + supportedFeatureIds: ['alerting'], + }, + ]); - it(`renders action types as disabled when disabled by license`, async () => { - const onActionTypeChange = jest.fn(); - const actionType = actionTypeRegistryMock.createMockActionTypeModel({ - id: 'my-action-type', - iconClass: 'test', - selectMessage: 'test', - validateParams: (): Promise> => { - const validationResult = { errors: {} }; - return Promise.resolve(validationResult); - }, - actionConnectorFields: null, + const wrapper = mountWithIntl( + + ); + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect( + wrapper.find('EuiToolTip [data-test-subj="my-action-type-card"]').exists() + ).toBeTruthy(); }); - actionTypeRegistry.get.mockReturnValueOnce(actionType); - loadActionTypes.mockResolvedValueOnce([ - { - id: actionType.id, - enabled: false, - name: 'Test', - enabledInConfig: true, - enabledInLicense: false, - minimumLicenseRequired: 'gold', - supportedFeatureIds: ['alerting'], - }, - ]); - - const wrapper = mountWithIntl( - - ); - await act(async () => { - await nextTick(); - wrapper.update(); + }); + + describe('beta badge', () => { + it(`does not render beta badge when isExperimental=false`, async () => { + const onActionTypeChange = jest.fn(); + const actionType = actionTypeRegistryMock.createMockActionTypeModel({ + id: 'my-action-type', + iconClass: 'test', + selectMessage: 'test', + validateParams: (): Promise> => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + isExperimental: false, + }); + actionTypeRegistry.get.mockReturnValueOnce(actionType); + loadActionTypes.mockResolvedValueOnce([ + { + id: actionType.id, + enabled: false, + name: 'Test', + enabledInConfig: true, + enabledInLicense: false, + minimumLicenseRequired: 'gold', + supportedFeatureIds: ['alerting'], + }, + ]); + + const wrapper = mountWithIntl( + + ); + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect( + wrapper.find('EuiToolTip [data-test-subj="my-action-type-card"] EuiBetaBadge').exists() + ).toBeFalsy(); }); - expect(wrapper.find('EuiToolTip [data-test-subj="my-action-type-card"]').exists()).toBeTruthy(); + it(`renders beta badge when isExperimental=true`, async () => { + const onActionTypeChange = jest.fn(); + const actionType = actionTypeRegistryMock.createMockActionTypeModel({ + id: 'my-action-type', + iconClass: 'test', + selectMessage: 'test', + validateParams: (): Promise> => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + isExperimental: true, + }); + actionTypeRegistry.get.mockReturnValueOnce(actionType); + loadActionTypes.mockResolvedValueOnce([ + { + id: actionType.id, + enabled: false, + name: 'Test', + enabledInConfig: true, + enabledInLicense: false, + minimumLicenseRequired: 'gold', + supportedFeatureIds: ['alerting'], + }, + ]); + + const wrapper = mountWithIntl( + + ); + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect( + wrapper.find('EuiToolTip [data-test-subj="my-action-type-card"] EuiBetaBadge').exists() + ).toBeTruthy(); + }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.test.tsx index a3cde0479d6f6..eb51e6e9475af 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.test.tsx @@ -16,6 +16,7 @@ import { createAppMockRenderer, } from '../../../components/builtin_action_types/test_utils'; import CreateConnectorFlyout from '.'; +import { betaBadgeProps } from '../beta_badge_props'; jest.mock('../../../lib/action_connector_api', () => ({ ...(jest.requireActual('../../../lib/action_connector_api') as any), @@ -79,6 +80,7 @@ describe('CreateConnectorFlyout', () => { onTestConnector={onTestConnector} /> ); + await act(() => Promise.resolve()); expect(getByTestId('create-connector-flyout')).toBeInTheDocument(); expect(getByTestId('create-connector-flyout-header')).toBeInTheDocument(); @@ -294,6 +296,33 @@ describe('CreateConnectorFlyout', () => { expect(getByText('Test connector')).toBeInTheDocument(); expect(getByText(`selectMessage-${actionTypeModel.id}`)).toBeInTheDocument(); }); + + it('does not show beta badge when isExperimental is false', async () => { + const { queryByText } = appMockRenderer.render( + + ); + await act(() => Promise.resolve()); + expect(queryByText(betaBadgeProps.label)).not.toBeInTheDocument(); + }); + + it('shows beta badge when isExperimental is true', async () => { + actionTypeRegistry.get.mockReturnValue({ ...actionTypeModel, isExperimental: true }); + const { getByText } = appMockRenderer.render( + + ); + await act(() => Promise.resolve()); + expect(getByText(betaBadgeProps.label)).toBeInTheDocument(); + }); }); describe('Submitting', () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.tsx index f34c5d4e6dc76..1cfd55f8d7ecc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.tsx @@ -149,7 +149,6 @@ const CreateConnectorFlyoutComponent: React.FC = ({ isMounted.current = false; }; }, []); - return ( Date: Tue, 26 Jul 2022 12:13:00 -0600 Subject: [PATCH 2/8] Rename incidentViewUrl to viewIncidentUrl --- .../server/builtin_action_types/cases_webhook/schema.ts | 2 +- .../builtin_action_types/cases_webhook/service.test.ts | 4 ++-- .../server/builtin_action_types/cases_webhook/service.ts | 8 ++++---- .../builtin_action_types/cases_webhook/validators.ts | 4 ++-- .../builtin_action_types/cases_webhook/steps/get.tsx | 6 +++--- .../builtin_action_types/cases_webhook/translations.ts | 4 ++-- .../cases_webhook/webhook_connectors.test.tsx | 8 ++++---- .../cases_webhook/webhook_connectors.tsx | 2 +- .../tests/actions/builtin_action_types/cases_webhook.ts | 4 ++-- .../tests/actions/builtin_action_types/cases_webhook.ts | 8 ++++---- x-pack/test/cases_api_integration/common/lib/utils.ts | 2 +- .../tests/trial/configure/get_connectors.ts | 2 +- .../spaces_only/tests/trial/configure/get_connectors.ts | 2 +- 13 files changed, 28 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/schema.ts index fafa0a64101b6..ca2f14a8f59be 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/schema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/schema.ts @@ -25,7 +25,7 @@ export const ExternalIncidentServiceConfiguration = { getIncidentResponseCreatedDateKey: schema.string(), getIncidentResponseExternalTitleKey: schema.string(), getIncidentResponseUpdatedDateKey: schema.string(), - incidentViewUrl: schema.string(), + viewIncidentUrl: schema.string(), updateIncidentUrl: schema.string(), updateIncidentMethod: schema.oneOf( [ diff --git a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.test.ts index fadd84073e858..ce585920c81f1 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.test.ts @@ -41,7 +41,7 @@ const config: CasesWebhookPublicConfigurationType = { getIncidentResponseUpdatedDateKey: 'fields.updated', hasAuth: true, headers: { ['content-type']: 'application/json' }, - incidentViewUrl: 'https://coolsite.net/browse/{{{external.system.title}}}', + viewIncidentUrl: 'https://coolsite.net/browse/{{{external.system.title}}}', getIncidentUrl: 'https://coolsite.net/issue/{{{external.system.id}}}', updateIncidentJson: '{"fields":{"title":{{{case.title}}},"description":{{{case.description}}},"tags":{{{case.tags}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', @@ -75,7 +75,7 @@ describe('Cases webhook service', () => { describe('createExternalService', () => { const requiredUrls = [ 'createIncidentUrl', - 'incidentViewUrl', + 'viewIncidentUrl', 'getIncidentUrl', 'updateIncidentUrl', ]; diff --git a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.ts b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.ts index 04b3e2fdbaff9..26551200a3b69 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/service.ts @@ -55,7 +55,7 @@ export const createExternalService = ( getIncidentUrl, hasAuth, headers, - incidentViewUrl, + viewIncidentUrl, updateIncidentJson, updateIncidentMethod, updateIncidentUrl, @@ -64,7 +64,7 @@ export const createExternalService = ( if ( !getIncidentUrl || !createIncidentUrlConfig || - !incidentViewUrl || + !viewIncidentUrl || !updateIncidentUrl || (hasAuth && (!password || !user)) ) { @@ -163,7 +163,7 @@ export const createExternalService = ( logger.debug(`response from webhook action "${actionId}": [HTTP ${status}] ${statusText}`); - const viewUrl = renderMustacheStringNoEscape(incidentViewUrl, { + const viewUrl = renderMustacheStringNoEscape(viewIncidentUrl, { external: { system: { id: encodeURIComponent(externalId), @@ -233,7 +233,7 @@ export const createExternalService = ( res, }); const updatedIncident = await getIncident(incidentId as string); - const viewUrl = renderMustacheStringNoEscape(incidentViewUrl, { + const viewUrl = renderMustacheStringNoEscape(viewIncidentUrl, { external: { system: { id: encodeURIComponent(incidentId), diff --git a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/validators.ts b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/validators.ts index 618ef2428f5fd..91e5ccbeb8715 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/validators.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/cases_webhook/validators.ts @@ -20,7 +20,7 @@ const validateConfig = ( const { createCommentUrl, createIncidentUrl, - incidentViewUrl, + viewIncidentUrl, getIncidentUrl, updateIncidentUrl, } = configObject; @@ -28,7 +28,7 @@ const validateConfig = ( const urls = [ createIncidentUrl, createCommentUrl, - incidentViewUrl, + viewIncidentUrl, getIncidentUrl, updateIncidentUrl, ]; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/get.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/get.tsx index b6f50715355fa..91afba02f1cce 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/get.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/get.tsx @@ -121,7 +121,7 @@ export const GetStep: FunctionComponent = ({ display, readOnly }) => ( = ({ display, readOnly }) => ( componentProps={{ euiFieldProps: { readOnly, - 'data-test-subj': 'incidentViewUrlText', + 'data-test-subj': 'viewIncidentUrlText', messageVariables: urlVarsExt, - paramsProperty: 'incidentViewUrl', + paramsProperty: 'viewIncidentUrl', buttonTitle: i18n.ADD_CASES_VARIABLE, showButtonTitle: true, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/translations.ts index 1e21e64228b17..643fac5e1e05c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/translations.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/translations.ts @@ -275,13 +275,13 @@ export const GET_INCIDENT_UPDATED_KEY_HELP = i18n.translate( ); export const EXTERNAL_INCIDENT_VIEW_URL = i18n.translate( - 'xpack.triggersActionsUI.components.builtinActionTypes.casesWebhookAction.incidentViewUrlTextFieldLabel', + 'xpack.triggersActionsUI.components.builtinActionTypes.casesWebhookAction.viewIncidentUrlTextFieldLabel', { defaultMessage: 'External Case View URL', } ); export const EXTERNAL_INCIDENT_VIEW_URL_HELP = i18n.translate( - 'xpack.triggersActionsUI.components.builtinActionTypes.casesWebhookAction.incidentViewUrlHelp', + 'xpack.triggersActionsUI.components.builtinActionTypes.casesWebhookAction.viewIncidentUrlHelp', { defaultMessage: 'URL to view case in external system. Use the variable selector to add external system id or external system title to the url.', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.test.tsx index 320759095e36b..6d1d74bbde287 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.test.tsx @@ -52,7 +52,7 @@ const config = { getIncidentResponseUpdatedDateKey: 'fields.updated', hasAuth: true, headers: [{ key: 'content-type', value: 'text' }], - incidentViewUrl: 'https://coolsite.net/browse/{{{external.system.title}}}', + viewIncidentUrl: 'https://coolsite.net/browse/{{{external.system.title}}}', getIncidentUrl: 'https://coolsite.net/rest/api/2/issue/{{{external.system.id}}}', updateIncidentJson: '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', @@ -96,7 +96,7 @@ describe('CasesWebhookActionConnectorFields renders', () => { expect(getByTestId('getIncidentResponseExternalTitleKeyText')).toBeInTheDocument(); expect(getByTestId('getIncidentResponseCreatedDateKeyText')).toBeInTheDocument(); expect(getByTestId('getIncidentResponseUpdatedDateKeyText')).toBeInTheDocument(); - expect(getByTestId('incidentViewUrlInput')).toBeInTheDocument(); + expect(getByTestId('viewIncidentUrlInput')).toBeInTheDocument(); expect(getByTestId('webhookUpdateMethodSelect')).toBeInTheDocument(); expect(getByTestId('updateIncidentUrlInput')).toBeInTheDocument(); expect(getByTestId('webhookUpdateIncidentJson')).toBeInTheDocument(); @@ -339,7 +339,7 @@ describe('CasesWebhookActionConnectorFields renders', () => { ['webhookCreateUrlText', 'not-valid'], ['webhookUserInput', ''], ['webhookPasswordInput', ''], - ['incidentViewUrlInput', 'https://missingexternalid.com'], + ['viewIncidentUrlInput', 'https://missingexternalid.com'], ['createIncidentResponseKeyText', ''], ['getIncidentUrlInput', 'https://missingexternalid.com'], ['getIncidentResponseExternalTitleKeyText', ''], @@ -356,7 +356,7 @@ describe('CasesWebhookActionConnectorFields renders', () => { ['updateIncidentJson', invalidJsonBoth, ['{{{case.title}}}', '{{{case.description}}}']], ['createCommentJson', invalidJsonBoth, ['{{{case.comment}}}']], [ - 'incidentViewUrl', + 'viewIncidentUrl', 'https://missingexternalid.com', ['{{{external.system.id}}}', '{{{external.system.title}}}'], ], diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.tsx index d828f8226b8df..a023edea737c5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/webhook_connectors.tsx @@ -42,7 +42,7 @@ const fields = { 'config.getIncidentResponseExternalTitleKey', 'config.getIncidentResponseCreatedDateKey', 'config.getIncidentResponseUpdatedDateKey', - 'config.incidentViewUrl', + 'config.viewIncidentUrl', ], step4: [ 'config.updateIncidentMethod', diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/cases_webhook.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/cases_webhook.ts index 81c3f9e58ceb5..602fa1e2fff00 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/cases_webhook.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/cases_webhook.ts @@ -31,7 +31,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { getIncidentResponseUpdatedDateKey: 'fields.updated', hasAuth: true, headers: { ['content-type']: 'application/json' }, - incidentViewUrl: 'https://coolsite.net/browse/{{{external.system.title}}}', + viewIncidentUrl: 'https://coolsite.net/browse/{{{external.system.title}}}', getIncidentUrl: 'https://coolsite.net/rest/api/2/issue/{{{external.system.id}}}', updateIncidentJson: '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"labels":{{{case.tags}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', @@ -79,7 +79,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { ...config, createCommentUrl: `${casesWebhookSimulatorURL}/{{{external.system.id}}}/comments`, createIncidentUrl: casesWebhookSimulatorURL, - incidentViewUrl: `${casesWebhookSimulatorURL}/{{{external.system.title}}}`, + viewIncidentUrl: `${casesWebhookSimulatorURL}/{{{external.system.title}}}`, getIncidentUrl: `${casesWebhookSimulatorURL}/{{{external.system.id}}}`, updateIncidentUrl: `${casesWebhookSimulatorURL}/{{{external.system.id}}}`, }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/builtin_action_types/cases_webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/builtin_action_types/cases_webhook.ts index 06fba292f58b0..40c8a21fa9b65 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/builtin_action_types/cases_webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/builtin_action_types/cases_webhook.ts @@ -35,7 +35,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { getIncidentResponseUpdatedDateKey: 'fields.updated', hasAuth: true, headers: { ['content-type']: 'application/json', ['kbn-xsrf']: 'abcd' }, - incidentViewUrl: 'https://coolsite.net/browse/{{{external.system.title}}}', + viewIncidentUrl: 'https://coolsite.net/browse/{{{external.system.title}}}', getIncidentUrl: 'https://coolsite.net/rest/api/2/issue/{{{external.system.id}}}', updateIncidentJson: '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"labels":{{{case.tags}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', @@ -49,7 +49,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { 'getIncidentResponseCreatedDateKey', 'getIncidentResponseExternalTitleKey', 'getIncidentResponseUpdatedDateKey', - 'incidentViewUrl', + 'viewIncidentUrl', 'getIncidentUrl', 'updateIncidentJson', 'updateIncidentUrl', @@ -92,7 +92,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { ...mockCasesWebhook.config, createCommentUrl: `${casesWebhookSimulatorURL}/rest/api/2/issue/{{{external.system.id}}}/comment`, createIncidentUrl: `${casesWebhookSimulatorURL}/rest/api/2/issue`, - incidentViewUrl: `${casesWebhookSimulatorURL}/browse/{{{external.system.title}}}`, + viewIncidentUrl: `${casesWebhookSimulatorURL}/browse/{{{external.system.title}}}`, getIncidentUrl: `${casesWebhookSimulatorURL}/rest/api/2/issue/{{{external.system.id}}}`, updateIncidentUrl: `${casesWebhookSimulatorURL}/rest/api/2/issue/{{{external.system.id}}}`, }; @@ -172,7 +172,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { ...mockCasesWebhook.config, createCommentUrl: `${badUrl}/{{{external.system.id}}}/comments`, createIncidentUrl: badUrl, - incidentViewUrl: `${badUrl}/{{{external.system.title}}}`, + viewIncidentUrl: `${badUrl}/{{{external.system.title}}}`, getIncidentUrl: `${badUrl}/{{{external.system.id}}}`, updateIncidentUrl: `${badUrl}/{{{external.system.id}}}`, }, diff --git a/x-pack/test/cases_api_integration/common/lib/utils.ts b/x-pack/test/cases_api_integration/common/lib/utils.ts index 5f68fafff85a4..1cc684ad81a0c 100644 --- a/x-pack/test/cases_api_integration/common/lib/utils.ts +++ b/x-pack/test/cases_api_integration/common/lib/utils.ts @@ -271,7 +271,7 @@ export const getCasesWebhookConnector = () => ({ getIncidentResponseUpdatedDateKey: 'fields.updated', hasAuth: true, headers: { [`content-type`]: 'application/json' }, - incidentViewUrl: 'http://some.non.existent.com/browse/{{{external.system.title}}}', + viewIncidentUrl: 'http://some.non.existent.com/browse/{{{external.system.title}}}', getIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', updateIncidentJson: '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts index 4109913d9f4fb..00b8c461c9554 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts @@ -76,7 +76,7 @@ export default ({ getService }: FtrProviderContext): void => { getIncidentResponseUpdatedDateKey: 'fields.updated', hasAuth: true, headers: { [`content-type`]: 'application/json' }, - incidentViewUrl: 'http://some.non.existent.com/browse/{{{external.system.title}}}', + viewIncidentUrl: 'http://some.non.existent.com/browse/{{{external.system.title}}}', getIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', updateIncidentJson: '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts index c6d2165f2bf8b..cf6aff833d24e 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts @@ -110,7 +110,7 @@ export default ({ getService }: FtrProviderContext): void => { getIncidentResponseUpdatedDateKey: 'fields.updated', hasAuth: true, headers: { [`content-type`]: 'application/json' }, - incidentViewUrl: 'http://some.non.existent.com/browse/{{{external.system.title}}}', + viewIncidentUrl: 'http://some.non.existent.com/browse/{{{external.system.title}}}', getIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', updateIncidentJson: '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', From 1c6168b42e304822098e643bae012be42c851d79 Mon Sep 17 00:00:00 2001 From: Steph Milovic Date: Tue, 26 Jul 2022 12:50:16 -0600 Subject: [PATCH 3/8] beta badge all over --- .../cases_webhook/steps/update.styles.ts | 16 +++ .../cases_webhook/steps/update.tsx | 3 + .../action_form.test.tsx | 125 ++++++++++++++++++ .../action_type_form.tsx | 10 ++ .../connector_add_inline.tsx | 7 + .../connector_add_modal.test.tsx | 80 +++++++++++ .../connector_add_modal.tsx | 10 ++ .../edit_connector_flyout/header.tsx | 20 ++- .../edit_connector_flyout/index.test.tsx | 28 ++++ .../edit_connector_flyout/index.tsx | 1 + 10 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/update.styles.ts diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/update.styles.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/update.styles.ts new file mode 100644 index 0000000000000..35f4b92aea5ba --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/update.styles.ts @@ -0,0 +1,16 @@ +/* + * 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 { css } from '@emotion/react'; + +export const styles = { + method: css` + .euiFormRow__labelWrapper { + margin-bottom: 12px; + } + `, +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/update.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/update.tsx index c8bfa4ad350b1..e8305e7439778 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/update.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/cases_webhook/steps/update.tsx @@ -15,6 +15,7 @@ import { MustacheTextFieldWrapper } from '../../../mustache_text_field_wrapper'; import { casesVars, commentVars, urlVars } from '../action_variables'; import { JsonFieldWrapper } from '../../../json_field_wrapper'; import { HTTP_VERBS } from '../webhook_connectors'; +import { styles } from './update.styles'; import * as i18n from '../translations'; const { emptyField, urlField } = fieldValidators; @@ -47,6 +48,7 @@ export const UpdateStep: FunctionComponent = ({ display, readOnly }) => ( }, ], }} + css={styles.method} componentProps={{ euiFieldProps: { 'data-test-subj': 'webhookUpdateMethodSelect', @@ -137,6 +139,7 @@ export const UpdateStep: FunctionComponent = ({ display, readOnly }) => ( }, ], }} + css={styles.method} componentProps={{ euiFieldProps: { 'data-test-subj': 'webhookCreateCommentMethodSelect', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index da439343f5873..3001717fb023e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -605,4 +605,129 @@ describe('action_form', () => { ).toHaveLength(2); }); }); + + describe('beta badge (action_type_form)', () => { + async function setup(isExperimental: boolean) { + const actionTypeRegistry = actionTypeRegistryMock.create(); + + const { loadAllActions } = jest.requireMock('../../lib/action_connector_api'); + loadAllActions.mockResolvedValueOnce(allActions); + const mocks = coreMock.createSetup(); + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + // eslint-disable-next-line react-hooks/rules-of-hooks + useKibanaMock().services.application.capabilities = { + ...capabilities, + actions: { + show: true, + save: true, + delete: true, + }, + }; + const newActionType = { + ...actionType, + isExperimental, + }; + actionTypeRegistry.list.mockReturnValue([newActionType]); + actionTypeRegistry.has.mockReturnValue(true); + actionTypeRegistry.get.mockReturnValue(newActionType); + const initialAlert = { + name: 'test', + params: {}, + consumer: 'alerts', + alertTypeId: alertType.id, + schedule: { + interval: '1m', + }, + actions: [ + { + group: 'default', + id: 'test', + actionTypeId: actionType.id, + params: { + message: '', + }, + }, + ], + tags: [], + muteAll: false, + enabled: false, + mutedInstanceIds: [], + } as unknown as Rule; + + loadActionTypes.mockResolvedValue([ + { + id: actionType.id, + name: 'Test', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + }, + ]); + + const defaultActionMessage = 'Alert [{{context.metadata.name}}] has exceeded the threshold'; + const wrapper = mountWithIntl( + { + const recoveryActionGroupId = 'recovered'; + return isActionGroupDisabledForActionTypeId( + actionGroupId === recoveryActionGroupId ? RecoveredActionGroup.id : actionGroupId, + actionTypeId + ); + }} + setActionIdByIndex={(id: string, index: number) => { + initialAlert.actions[index].id = id; + }} + actionGroups={[ + { id: 'default', name: 'Default', defaultActionMessage }, + { + id: 'recovered', + name: 'Recovered', + }, + ]} + setActionGroupIdByIndex={(group: string, index: number) => { + initialAlert.actions[index].group = group; + }} + setActions={(_updatedActions: RuleAction[]) => {}} + setActionParamsProperty={(key: string, value: any, index: number) => + (initialAlert.actions[index] = { ...initialAlert.actions[index], [key]: value }) + } + actionTypeRegistry={actionTypeRegistry} + setHasActionsWithBrokenConnector={setHasActionsWithBrokenConnector} + /> + ); + + // Wait for active space to resolve before requesting the component to update + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + return wrapper; + } + it(`does not render beta badge when isExperimental=false`, async () => { + const wrapper = await setup(false); + expect(wrapper.find('EuiBetaBadge').exists()).toBeFalsy(); + }); + it(`renders beta badge when isExperimental=tru`, async () => { + const wrapper = await setup(true); + expect(wrapper.find('EuiBetaBadge').exists()).toBeTruthy(); + }); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx index b03157c511fed..1e2a8d91c40bf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx @@ -24,9 +24,11 @@ import { EuiBadge, EuiErrorBoundary, EuiToolTip, + EuiBetaBadge, } from '@elastic/eui'; import { isEmpty, partition, some } from 'lodash'; import { ActionVariable, RuleActionParam } from '@kbn/alerting-plugin/common'; +import { betaBadgeProps } from './beta_badge_props'; import { IErrorObject, RuleAction, @@ -341,6 +343,14 @@ export const ActionTypeForm = ({ + {actionTypeRegistered && actionTypeRegistered.isExperimental && ( + + + + )} } extraAction={ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_inline.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_inline.tsx index 558ae873892da..95103eea63932 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_inline.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_inline.tsx @@ -22,7 +22,9 @@ import { EuiFormRow, EuiButtonEmpty, EuiIconTip, + EuiBetaBadge, } from '@elastic/eui'; +import { betaBadgeProps } from './beta_badge_props'; import { RuleAction, ActionTypeIndex, ActionConnector } from '../../../types'; import { hasSaveActionsCapability } from '../../lib/capabilities'; import { ActionAccordionFormProps } from './action_form'; @@ -179,6 +181,11 @@ export const AddConnectorInline = ({ /> )} + {actionTypeRegistered && actionTypeRegistered.isExperimental && ( + + + + )} } extraAction={ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx index fe29f363c388f..fcc80ace505ff 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx @@ -75,4 +75,84 @@ describe('connector_add_modal', () => { expect(wrapper.exists('.euiModalHeader')).toBeTruthy(); expect(wrapper.exists('[data-test-subj="saveActionButtonModal"]')).toBeTruthy(); }); + + describe('beta badge', () => { + it(`does not render beta badge when isExperimental=false`, async () => { + const actionTypeModel = actionTypeRegistryMock.createMockActionTypeModel({ + id: 'my-action-type', + iconClass: 'test', + isExperimental: false, + selectMessage: 'test', + validateParams: (): Promise> => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + }); + actionTypeRegistry.get.mockReturnValue(actionTypeModel); + actionTypeRegistry.has.mockReturnValue(true); + + const actionType: ActionType = { + id: 'my-action-type', + name: 'test', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + }; + const wrapper = mountWithIntl( + {}} + actionType={actionType} + actionTypeRegistry={actionTypeRegistry} + /> + ); + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find('EuiBetaBadge').exists()).toBeFalsy(); + }); + + it(`renders beta badge when isExperimental=true`, async () => { + const actionTypeModel = actionTypeRegistryMock.createMockActionTypeModel({ + id: 'my-action-type', + iconClass: 'test', + isExperimental: true, + selectMessage: 'test', + validateParams: (): Promise> => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + }); + actionTypeRegistry.get.mockReturnValue(actionTypeModel); + actionTypeRegistry.has.mockReturnValue(true); + + const actionType: ActionType = { + id: 'my-action-type', + name: 'test', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + }; + const wrapper = mountWithIntl( + {}} + actionType={actionType} + actionTypeRegistry={actionTypeRegistry} + /> + ); + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find('EuiBetaBadge').exists()).toBeTruthy(); + }); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index 0b8095f0058eb..5aa31056e1355 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -19,9 +19,11 @@ import { EuiFlexItem, EuiIcon, EuiFlexGroup, + EuiBetaBadge, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import './connector_add_modal.scss'; +import { betaBadgeProps } from './beta_badge_props'; import { hasSaveActionsCapability } from '../../lib/capabilities'; import { ActionType, ActionConnector, ActionTypeRegistryContract } from '../../../types'; import { useKibana } from '../../../common/lib/kibana'; @@ -153,6 +155,14 @@ const ConnectorAddModal = ({ + {actionTypeModel && actionTypeModel.isExperimental && ( + + + + )} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx index 9e3f5d58f0b55..75b4068a8eba4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx @@ -22,16 +22,26 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; +import { betaBadgeProps } from '../beta_badge_props'; import { EditConnectorTabs } from '../../../../types'; const FlyoutHeaderComponent: React.FC<{ + isExperimental?: boolean; isPreconfigured: boolean; connectorName: string; connectorTypeDesc: string; selectedTab: EditConnectorTabs; setTab: () => void; icon?: IconType | null; -}> = ({ icon, isPreconfigured, connectorName, connectorTypeDesc, selectedTab, setTab }) => { +}> = ({ + icon, + isExperimental = false, + isPreconfigured, + connectorName, + connectorTypeDesc, + selectedTab, + setTab, +}) => { const { euiTheme } = useEuiTheme(); return ( @@ -84,6 +94,14 @@ const FlyoutHeaderComponent: React.FC<{ )} + {isExperimental && ( + + + + )} { expect(getByTestId('preconfiguredBadge')).toBeInTheDocument(); }); + + it('does not show beta badge when isExperimental is false', async () => { + const { queryByText } = appMockRenderer.render( + + ); + await act(() => Promise.resolve()); + expect(queryByText(betaBadgeProps.label)).not.toBeInTheDocument(); + }); + + it('shows beta badge when isExperimental is true', async () => { + actionTypeRegistry.get.mockReturnValue({ ...actionTypeModel, isExperimental: true }); + const { getByText } = appMockRenderer.render( + + ); + await act(() => Promise.resolve()); + expect(getByText(betaBadgeProps.label)).toBeInTheDocument(); + }); }); describe('Tabs', () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx index 4880cf10a1718..452a89d04f9c1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx @@ -246,6 +246,7 @@ const EditConnectorFlyoutComponent: React.FC = ({ setTab={handleSetTab} selectedTab={selectedTab} icon={actionTypeModel?.iconClass} + isExperimental={actionTypeModel?.isExperimental} /> {selectedTab === EditConnectorTabs.Configuration ? ( From 63c4f328940585a6b01c6031958ac5c4529d88bd Mon Sep 17 00:00:00 2001 From: Steph Milovic Date: Wed, 27 Jul 2022 09:54:48 -0600 Subject: [PATCH 4/8] fix big whoops --- .../sections/action_connector_form/connector_add_inline.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_inline.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_inline.tsx index 95103eea63932..e88799c5faf68 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_inline.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_inline.tsx @@ -183,7 +183,10 @@ export const AddConnectorInline = ({ )} {actionTypeRegistered && actionTypeRegistered.isExperimental && ( - + )} From 751615e8b280eed2646374a0f5ab3ae18a588517 Mon Sep 17 00:00:00 2001 From: Steph Milovic Date: Wed, 27 Jul 2022 12:01:49 -0600 Subject: [PATCH 5/8] pr fixes --- .../action_form.test.tsx | 471 +++++++----------- .../action_connector_form/action_form.tsx | 5 + .../action_type_form.tsx | 1 + .../action_type_menu.test.tsx | 40 ++ .../connector_add_modal.scss | 4 + .../connector_add_modal.tsx | 2 +- .../create_connector_flyout/index.test.tsx | 14 + .../create_connector_flyout/index.tsx | 1 + 8 files changed, 255 insertions(+), 283 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 3001717fb023e..dc66f0cb594c9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -180,173 +180,181 @@ describe('action_form', () => { const useKibanaMock = useKibana as jest.Mocked; - describe('action_form in alert', () => { - async function setup(customActions?: RuleAction[], customRecoveredActionGroup?: string) { - const actionTypeRegistry = actionTypeRegistryMock.create(); - - const { loadAllActions } = jest.requireMock('../../lib/action_connector_api'); - loadAllActions.mockResolvedValueOnce(allActions); - const mocks = coreMock.createSetup(); - const [ - { - application: { capabilities }, - }, - ] = await mocks.getStartServices(); - // eslint-disable-next-line react-hooks/rules-of-hooks - useKibanaMock().services.application.capabilities = { - ...capabilities, - actions: { - show: true, - save: true, - delete: true, - }, - }; - actionTypeRegistry.list.mockReturnValue([ - actionType, - disabledByConfigActionType, - disabledByLicenseActionType, - disabledByActionType, - preconfiguredOnly, - ]); - actionTypeRegistry.has.mockReturnValue(true); - actionTypeRegistry.get.mockReturnValue(actionType); - const initialAlert = { - name: 'test', - params: {}, - consumer: 'alerts', - alertTypeId: alertType.id, - schedule: { - interval: '1m', - }, - actions: customActions - ? customActions - : [ - { - group: 'default', - id: 'test', - actionTypeId: actionType.id, - params: { - message: '', - }, - }, - ], - tags: [], - muteAll: false, - enabled: false, - mutedInstanceIds: [], - } as unknown as Rule; - - loadActionTypes.mockResolvedValue([ - { - id: actionType.id, - name: 'Test', - enabled: true, - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'basic', - supportedFeatureIds: ['alerting'], - }, - { - id: '.index', - name: 'Index', - enabled: true, - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'basic', - supportedFeatureIds: ['alerting'], - }, - { - id: 'preconfigured', - name: 'Preconfigured only', - enabled: true, - enabledInConfig: false, - enabledInLicense: true, - minimumLicenseRequired: 'basic', - supportedFeatureIds: ['alerting'], - }, - { - id: 'disabled-by-config', - name: 'Disabled by config', - enabled: false, - enabledInConfig: false, - enabledInLicense: true, - minimumLicenseRequired: 'gold', - supportedFeatureIds: ['alerting'], - }, - { - id: 'disabled-by-license', - name: 'Disabled by license', - enabled: false, - enabledInConfig: true, - enabledInLicense: false, - minimumLicenseRequired: 'gold', - supportedFeatureIds: ['alerting'], - }, - { - id: '.jira', - name: 'Disabled by action type', - enabled: true, - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'basic', - supportedFeatureIds: ['alerting'], - }, - ]); - - const defaultActionMessage = 'Alert [{{context.metadata.name}}] has exceeded the threshold'; - const wrapper = mountWithIntl( - { - const recoveryActionGroupId = customRecoveredActionGroup - ? customRecoveredActionGroup - : 'recovered'; - return isActionGroupDisabledForActionTypeId( - actionGroupId === recoveryActionGroupId ? RecoveredActionGroup.id : actionGroupId, - actionTypeId - ); - }} - setActionIdByIndex={(id: string, index: number) => { - initialAlert.actions[index].id = id; - }} - actionGroups={[ - { id: 'default', name: 'Default', defaultActionMessage }, + async function setup( + customActions?: RuleAction[], + customRecoveredActionGroup?: string, + isExperimental?: boolean + ) { + const actionTypeRegistry = actionTypeRegistryMock.create(); + + const { loadAllActions } = jest.requireMock('../../lib/action_connector_api'); + loadAllActions.mockResolvedValueOnce(allActions); + const mocks = coreMock.createSetup(); + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + // eslint-disable-next-line react-hooks/rules-of-hooks + useKibanaMock().services.application.capabilities = { + ...capabilities, + actions: { + show: true, + save: true, + delete: true, + }, + }; + const newActionType = { + ...actionType, + isExperimental, + }; + actionTypeRegistry.list.mockReturnValue([ + newActionType, + disabledByConfigActionType, + disabledByLicenseActionType, + disabledByActionType, + preconfiguredOnly, + ]); + actionTypeRegistry.has.mockReturnValue(true); + actionTypeRegistry.get.mockReturnValue(newActionType); + const initialAlert = { + name: 'test', + params: {}, + consumer: 'alerts', + alertTypeId: alertType.id, + schedule: { + interval: '1m', + }, + actions: customActions + ? customActions + : [ { - id: customRecoveredActionGroup ? customRecoveredActionGroup : 'recovered', - name: customRecoveredActionGroup ? 'I feel better' : 'Recovered', + group: 'default', + id: 'test', + actionTypeId: newActionType.id, + params: { + message: '', + }, }, - ]} - setActionGroupIdByIndex={(group: string, index: number) => { - initialAlert.actions[index].group = group; - }} - setActions={(_updatedActions: RuleAction[]) => {}} - setActionParamsProperty={(key: string, value: any, index: number) => - (initialAlert.actions[index] = { ...initialAlert.actions[index], [key]: value }) - } - actionTypeRegistry={actionTypeRegistry} - setHasActionsWithBrokenConnector={setHasActionsWithBrokenConnector} - /> - ); - - // Wait for active space to resolve before requesting the component to update - await act(async () => { - await nextTick(); - wrapper.update(); - }); + ], + tags: [], + muteAll: false, + enabled: false, + mutedInstanceIds: [], + } as unknown as Rule; + + loadActionTypes.mockResolvedValue([ + { + id: newActionType.id, + name: 'Test', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + }, + { + id: '.index', + name: 'Index', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + }, + { + id: 'preconfigured', + name: 'Preconfigured only', + enabled: true, + enabledInConfig: false, + enabledInLicense: true, + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + }, + { + id: 'disabled-by-config', + name: 'Disabled by config', + enabled: false, + enabledInConfig: false, + enabledInLicense: true, + minimumLicenseRequired: 'gold', + supportedFeatureIds: ['alerting'], + }, + { + id: 'disabled-by-license', + name: 'Disabled by license', + enabled: false, + enabledInConfig: true, + enabledInLicense: false, + minimumLicenseRequired: 'gold', + supportedFeatureIds: ['alerting'], + }, + { + id: '.jira', + name: 'Disabled by action type', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + }, + ]); + + const defaultActionMessage = 'Alert [{{context.metadata.name}}] has exceeded the threshold'; + const wrapper = mountWithIntl( + { + const recoveryActionGroupId = customRecoveredActionGroup + ? customRecoveredActionGroup + : 'recovered'; + return isActionGroupDisabledForActionTypeId( + actionGroupId === recoveryActionGroupId ? RecoveredActionGroup.id : actionGroupId, + actionTypeId + ); + }} + setActionIdByIndex={(id: string, index: number) => { + initialAlert.actions[index].id = id; + }} + actionGroups={[ + { id: 'default', name: 'Default', defaultActionMessage }, + { + id: customRecoveredActionGroup ? customRecoveredActionGroup : 'recovered', + name: customRecoveredActionGroup ? 'I feel better' : 'Recovered', + }, + ]} + setActionGroupIdByIndex={(group: string, index: number) => { + initialAlert.actions[index].group = group; + }} + setActions={(_updatedActions: RuleAction[]) => {}} + setActionParamsProperty={(key: string, value: any, index: number) => + (initialAlert.actions[index] = { ...initialAlert.actions[index], [key]: value }) + } + actionTypeRegistry={actionTypeRegistry} + setHasActionsWithBrokenConnector={setHasActionsWithBrokenConnector} + /> + ); + + // Wait for active space to resolve before requesting the component to update + await act(async () => { + await nextTick(); + wrapper.update(); + }); - return wrapper; - } + return wrapper; + } + describe('action_form in alert', () => { it('renders available action cards', async () => { const wrapper = await setup(); const actionOption = wrapper.find( @@ -607,127 +615,26 @@ describe('action_form', () => { }); describe('beta badge (action_type_form)', () => { - async function setup(isExperimental: boolean) { - const actionTypeRegistry = actionTypeRegistryMock.create(); - - const { loadAllActions } = jest.requireMock('../../lib/action_connector_api'); - loadAllActions.mockResolvedValueOnce(allActions); - const mocks = coreMock.createSetup(); - const [ - { - application: { capabilities }, - }, - ] = await mocks.getStartServices(); - // eslint-disable-next-line react-hooks/rules-of-hooks - useKibanaMock().services.application.capabilities = { - ...capabilities, - actions: { - show: true, - save: true, - delete: true, - }, - }; - const newActionType = { - ...actionType, - isExperimental, - }; - actionTypeRegistry.list.mockReturnValue([newActionType]); - actionTypeRegistry.has.mockReturnValue(true); - actionTypeRegistry.get.mockReturnValue(newActionType); - const initialAlert = { - name: 'test', - params: {}, - consumer: 'alerts', - alertTypeId: alertType.id, - schedule: { - interval: '1m', - }, - actions: [ - { - group: 'default', - id: 'test', - actionTypeId: actionType.id, - params: { - message: '', - }, - }, - ], - tags: [], - muteAll: false, - enabled: false, - mutedInstanceIds: [], - } as unknown as Rule; - - loadActionTypes.mockResolvedValue([ - { - id: actionType.id, - name: 'Test', - enabled: true, - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'basic', - supportedFeatureIds: ['alerting'], - }, - ]); - - const defaultActionMessage = 'Alert [{{context.metadata.name}}] has exceeded the threshold'; - const wrapper = mountWithIntl( - { - const recoveryActionGroupId = 'recovered'; - return isActionGroupDisabledForActionTypeId( - actionGroupId === recoveryActionGroupId ? RecoveredActionGroup.id : actionGroupId, - actionTypeId - ); - }} - setActionIdByIndex={(id: string, index: number) => { - initialAlert.actions[index].id = id; - }} - actionGroups={[ - { id: 'default', name: 'Default', defaultActionMessage }, - { - id: 'recovered', - name: 'Recovered', - }, - ]} - setActionGroupIdByIndex={(group: string, index: number) => { - initialAlert.actions[index].group = group; - }} - setActions={(_updatedActions: RuleAction[]) => {}} - setActionParamsProperty={(key: string, value: any, index: number) => - (initialAlert.actions[index] = { ...initialAlert.actions[index], [key]: value }) - } - actionTypeRegistry={actionTypeRegistry} - setHasActionsWithBrokenConnector={setHasActionsWithBrokenConnector} - /> - ); - - // Wait for active space to resolve before requesting the component to update - await act(async () => { - await nextTick(); - wrapper.update(); - }); - - return wrapper; - } + it(`does not render beta badge when isExperimental=undefined`, async () => { + const wrapper = await setup(); + expect(wrapper.find('EuiKeyPadMenuItem EuiBetaBadge').exists()).toBeFalsy(); + expect( + wrapper.find('EuiBetaBadge[data-test-subj="action-type-form-beta-badge"]').exists() + ).toBeFalsy(); + }); it(`does not render beta badge when isExperimental=false`, async () => { - const wrapper = await setup(false); - expect(wrapper.find('EuiBetaBadge').exists()).toBeFalsy(); + const wrapper = await setup(undefined, undefined, false); + expect(wrapper.find('EuiKeyPadMenuItem EuiBetaBadge').exists()).toBeFalsy(); + expect( + wrapper.find('EuiBetaBadge[data-test-subj="action-type-form-beta-badge"]').exists() + ).toBeFalsy(); }); - it(`renders beta badge when isExperimental=tru`, async () => { - const wrapper = await setup(true); - expect(wrapper.find('EuiBetaBadge').exists()).toBeTruthy(); + it(`renders beta badge when isExperimental=true`, async () => { + const wrapper = await setup(undefined, undefined, true); + expect(wrapper.find('EuiKeyPadMenuItem EuiBetaBadge').exists()).toBeTruthy(); + expect( + wrapper.find('EuiBetaBadge[data-test-subj="action-type-form-beta-badge"]').exists() + ).toBeTruthy(); }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index 391b0b6035000..06978dc8c13ea 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -20,6 +20,7 @@ import { EuiLink, } from '@elastic/eui'; import { ActionGroup, RuleActionParam } from '@kbn/alerting-plugin/common'; +import { betaBadgeProps } from './beta_badge_props'; import { loadActionTypes, loadAllActions as loadConnectors } from '../../lib/action_connector_api'; import { ActionTypeModel, @@ -256,6 +257,10 @@ export const ActionForm = ({ isDisabled={!checkEnabledResult.isEnabled} data-test-subj={`${item.id}-${featureId}-ActionTypeSelectOption`} label={actionTypesIndex[item.id].name} + betaBadgeLabel={item.isExperimental ? betaBadgeProps.label : undefined} + betaBadgeTooltipContent={ + item.isExperimental ? betaBadgeProps.tooltipContent : undefined + } onClick={() => addActionType(item)} > diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx index 702ee340d57f8..370e61b9fe5dc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx @@ -168,6 +168,46 @@ describe('connector_add_flyout', () => { }); describe('beta badge', () => { + it(`does not render beta badge when isExperimental=undefined`, async () => { + const onActionTypeChange = jest.fn(); + const actionType = actionTypeRegistryMock.createMockActionTypeModel({ + id: 'my-action-type', + iconClass: 'test', + selectMessage: 'test', + validateParams: (): Promise> => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + }); + actionTypeRegistry.get.mockReturnValueOnce(actionType); + loadActionTypes.mockResolvedValueOnce([ + { + id: actionType.id, + enabled: false, + name: 'Test', + enabledInConfig: true, + enabledInLicense: false, + minimumLicenseRequired: 'gold', + supportedFeatureIds: ['alerting'], + }, + ]); + + const wrapper = mountWithIntl( + + ); + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect( + wrapper.find('EuiToolTip [data-test-subj="my-action-type-card"] EuiBetaBadge').exists() + ).toBeFalsy(); + }); it(`does not render beta badge when isExperimental=false`, async () => { const onActionTypeChange = jest.fn(); const actionType = actionTypeRegistryMock.createMockActionTypeModel({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.scss b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.scss index 7f56c220db4bb..76f4843bfbc77 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.scss +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.scss @@ -5,3 +5,7 @@ .euiComboBoxOptionsList { z-index: 9001; } +.betaBadgeFlexItem.euiFlexItem.euiFlexItem--flexGrowZero { + margin-top: 10px; + margin-bottom: 3px; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index 5aa31056e1355..3c73acfc69118 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -156,7 +156,7 @@ const ConnectorAddModal = ({ {actionTypeModel && actionTypeModel.isExperimental && ( - + { expect(getByText(`selectMessage-${actionTypeModel.id}`)).toBeInTheDocument(); }); + it('does not show beta badge when isExperimental is undefined', async () => { + const { queryByText } = appMockRenderer.render( + + ); + await act(() => Promise.resolve()); + expect(queryByText(betaBadgeProps.label)).not.toBeInTheDocument(); + }); + it('does not show beta badge when isExperimental is false', async () => { + actionTypeRegistry.get.mockReturnValue({ ...actionTypeModel, isExperimental: false }); const { queryByText } = appMockRenderer.render( = ({ isMounted.current = false; }; }, []); + return ( Date: Thu, 28 Jul 2022 13:21:28 -0600 Subject: [PATCH 6/8] better badge alignment --- .../sections/action_connector_form/connector_add_modal.tsx | 2 +- .../action_connector_form/create_connector_flyout/header.tsx | 2 +- .../action_connector_form/edit_connector_flyout/header.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index 3c73acfc69118..29c9ff6f1af35 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -142,7 +142,7 @@ const ConnectorAddModal = ({ ) : null} - +

= ({ ) : null} - + {actionTypeName && actionTypeMessage ? ( <> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx index 75b4068a8eba4..f021f1af4f929 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx @@ -52,7 +52,7 @@ const FlyoutHeaderComponent: React.FC<{ ) : null} - + {isPreconfigured ? ( <> From 138521e38e91f352b04fb87a034ed9b51893b409 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Fri, 29 Jul 2022 17:31:05 +0300 Subject: [PATCH 7/8] Improve beta badge alignment --- .../connector_add_modal.tsx | 42 ++++++----- .../create_connector_flyout/header.tsx | 42 ++++++----- .../edit_connector_flyout/header.tsx | 69 ++++++++++++------- 3 files changed, 89 insertions(+), 64 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index 29c9ff6f1af35..0fefaef24129e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -143,26 +143,30 @@ const ConnectorAddModal = ({ ) : null} - -

- -

-
+ + + +

+ +

+
+
+ {actionTypeModel && actionTypeModel.isExperimental && ( + + + + )} +
- {actionTypeModel && actionTypeModel.isExperimental && ( - - - - )} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/header.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/header.tsx index 8f4eaa42e52b3..6369ec5a2dcbf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/header.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/header.tsx @@ -48,17 +48,29 @@ const FlyoutHeaderComponent: React.FC = ({ {actionTypeName && actionTypeMessage ? ( <> - -

- -

-
+ + + +

+ +

+
+
+ {actionTypeName && isExperimental && ( + + + + )} +
{actionTypeMessage} @@ -96,14 +108,6 @@ const FlyoutHeaderComponent: React.FC = ({ )}
- {actionTypeName && isExperimental && ( - - - - )} ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx index f021f1af4f929..33fee16200627 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/header.tsx @@ -55,14 +55,19 @@ const FlyoutHeaderComponent: React.FC<{ {isPreconfigured ? ( <> - -

- -   + + + +

+ +

+
+
+ -

-
+
+ + {isExperimental && ( + + )} + + ) : ( - -

- -

-
+ + + +

+ +

+
+
+ {isExperimental && ( + + + + )} +
)}
- {isExperimental && ( - - - - )} Date: Fri, 29 Jul 2022 17:44:18 +0300 Subject: [PATCH 8/8] Remove style --- .../sections/action_connector_form/connector_add_modal.scss | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.scss b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.scss index 76f4843bfbc77..7f56c220db4bb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.scss +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.scss @@ -5,7 +5,3 @@ .euiComboBoxOptionsList { z-index: 9001; } -.betaBadgeFlexItem.euiFlexItem.euiFlexItem--flexGrowZero { - margin-top: 10px; - margin-bottom: 3px; -}