diff --git a/.eslintrc.js b/.eslintrc.js index a4ce657d523d95..22d0270a5b066b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1370,7 +1370,7 @@ module.exports = { { // Source files only - allow `any` in test/mock files files: ['x-pack/plugins/enterprise_search/**/*.{ts,tsx}'], - excludedFiles: ['x-pack/plugins/enterprise_search/**/*.{test,mock}.{ts,tsx}'], + excludedFiles: ['x-pack/plugins/enterprise_search/**/*.{test,mock,test_helper}.{ts,tsx}'], rules: { '@typescript-eslint/no-explicit-any': 'error', }, diff --git a/api_docs/cases.json b/api_docs/cases.json index 55ec344cb0bcb2..bc92995dff6e91 100644 --- a/api_docs/cases.json +++ b/api_docs/cases.json @@ -1035,7 +1035,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 53 + "lineNumber": 49 }, "deprecated": false, "children": [ @@ -1051,7 +1051,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 53 + "lineNumber": 49 }, "deprecated": false, "isRequired": true @@ -1074,7 +1074,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 59 + "lineNumber": 55 }, "deprecated": false, "children": [ @@ -1091,7 +1091,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 60 + "lineNumber": 56 }, "deprecated": false, "isRequired": true @@ -1108,7 +1108,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 61 + "lineNumber": 57 }, "deprecated": false, "isRequired": true @@ -1129,7 +1129,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 75 + "lineNumber": 71 }, "deprecated": false, "children": [ @@ -1145,7 +1145,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 76 + "lineNumber": 72 }, "deprecated": false, "isRequired": true @@ -1170,7 +1170,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 24 + "lineNumber": 20 }, "deprecated": true, "references": [], @@ -1187,7 +1187,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 24 + "lineNumber": 20 }, "deprecated": false, "isRequired": true @@ -1634,62 +1634,6 @@ "returnComment": [], "initialIsOpen": false }, - { - "parentPluginId": "cases", - "id": "def-common.OmitProp", - "type": "Function", - "tags": [], - "label": "OmitProp", - "description": [], - "signature": [ - "(o: O, k: K) => Pick>" - ], - "source": { - "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 17 - }, - "deprecated": false, - "children": [ - { - "parentPluginId": "cases", - "id": "def-common.OmitProp.$1", - "type": "Uncategorized", - "tags": [], - "label": "o", - "description": [], - "signature": [ - "O" - ], - "source": { - "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 17 - }, - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "cases", - "id": "def-common.OmitProp.$2", - "type": "Uncategorized", - "tags": [], - "label": "k", - "description": [], - "signature": [ - "K" - ], - "source": { - "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 17 - }, - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "cases", "id": "def-common.throwErrors", @@ -1704,7 +1648,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 55 + "lineNumber": 51 }, "deprecated": false, "children": [ @@ -1720,7 +1664,7 @@ ], "source": { "path": "x-pack/plugins/cases/common/api/runtime_types.ts", - "lineNumber": 55 + "lineNumber": 51 }, "deprecated": false, "isRequired": true @@ -5278,7 +5222,7 @@ "section": "def-common.ConnectorTypes", "text": "ConnectorTypes" }, - ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; owner: string; } & { created_at: string; created_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; updated_at: string | null; updated_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; } | null; } & { mappings: { action_type: \"append\" | \"overwrite\" | \"nothing\"; source: \"description\" | \"title\" | \"comments\"; target: string; }[]; owner: string; } & { id: string; version: string; error: string | null; owner: string; })[]" + ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; } & { owner: string; } & { created_at: string; created_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; updated_at: string | null; updated_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; } | null; } & { mappings: { action_type: \"append\" | \"overwrite\" | \"nothing\"; source: \"description\" | \"title\" | \"comments\"; target: string; }[]; owner: string; } & { id: string; version: string; error: string | null; owner: string; })[]" ], "source": { "path": "x-pack/plugins/cases/common/api/cases/configure.ts", @@ -5335,7 +5279,7 @@ "section": "def-common.ConnectorTypes", "text": "ConnectorTypes" }, - ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; owner: string; }" + ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; } & { owner: string; }" ], "source": { "path": "x-pack/plugins/cases/common/api/cases/configure.ts", @@ -5392,7 +5336,7 @@ "section": "def-common.ConnectorTypes", "text": "ConnectorTypes" }, - ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; owner: string; } & { created_at: string; created_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; updated_at: string | null; updated_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; } | null; }" + ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; } & { owner: string; } & { created_at: string; created_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; updated_at: string | null; updated_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; } | null; }" ], "source": { "path": "x-pack/plugins/cases/common/api/cases/configure.ts", @@ -5506,7 +5450,7 @@ "section": "def-common.ConnectorTypes", "text": "ConnectorTypes" }, - ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; owner: string; }" + ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; } & { owner: string; }" ], "source": { "path": "x-pack/plugins/cases/common/api/cases/configure.ts", @@ -5563,7 +5507,7 @@ "section": "def-common.ConnectorTypes", "text": "ConnectorTypes" }, - ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; owner: string; } & { created_at: string; created_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; updated_at: string | null; updated_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; } | null; } & { mappings: { action_type: \"append\" | \"overwrite\" | \"nothing\"; source: \"description\" | \"title\" | \"comments\"; target: string; }[]; owner: string; } & { id: string; version: string; error: string | null; owner: string; }" + ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; } & { owner: string; } & { created_at: string; created_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; updated_at: string | null; updated_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; } | null; } & { mappings: { action_type: \"append\" | \"overwrite\" | \"nothing\"; source: \"description\" | \"title\" | \"comments\"; target: string; }[]; owner: string; } & { id: string; version: string; error: string | null; owner: string; }" ], "source": { "path": "x-pack/plugins/cases/common/api/cases/configure.ts", @@ -7187,7 +7131,7 @@ "section": "def-common.ConnectorTypes", "text": "ConnectorTypes" }, - ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; owner: string; } & { created_at: string; created_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; updated_at: string | null; updated_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; } | null; }, \"updated_at\" | \"owner\" | \"created_at\" | \"created_by\" | \"updated_by\" | \"closure_type\"> & { connector: ", + ".none; fields: null; }); closure_type: \"close-by-user\" | \"close-by-pushing\"; } & { owner: string; } & { created_at: string; created_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; updated_at: string | null; updated_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; } | null; }, \"updated_at\" | \"owner\" | \"created_at\" | \"created_by\" | \"updated_by\" | \"closure_type\"> & { connector: ", { "pluginId": "cases", "scope": "common", @@ -7359,6 +7303,40 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "cases", + "id": "def-common.MAX_CONCURRENT_SEARCHES", + "type": "number", + "tags": [], + "label": "MAX_CONCURRENT_SEARCHES", + "description": [], + "signature": [ + "10" + ], + "source": { + "path": "x-pack/plugins/cases/common/constants.ts", + "lineNumber": 97 + }, + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "cases", + "id": "def-common.MAX_DOCS_PER_PAGE", + "type": "number", + "tags": [], + "label": "MAX_DOCS_PER_PAGE", + "description": [], + "signature": [ + "10000" + ], + "source": { + "path": "x-pack/plugins/cases/common/constants.ts", + "lineNumber": 96 + }, + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "cases", "id": "def-common.MAX_GENERATED_ALERTS_PER_SUB_CASE", @@ -9365,6 +9343,8 @@ "<[", "IntersectionC", "<[", + "IntersectionC", + "<[", "TypeC", "<{ connector: ", "IntersectionC", @@ -9572,9 +9552,11 @@ "LiteralC", "<\"close-by-user\">, ", "LiteralC", - "<\"close-by-pushing\">]>; owner: ", + "<\"close-by-pushing\">]>; }>, ", + "TypeC", + "<{ owner: ", "StringC", - "; }>, ", + "; }>]>, ", "TypeC", "<{ created_at: ", "StringC", @@ -9701,6 +9683,8 @@ "label": "CaseConfigureAttributesRt", "description": [], "signature": [ + "IntersectionC", + "<[", "IntersectionC", "<[", "TypeC", @@ -9910,9 +9894,11 @@ "LiteralC", "<\"close-by-user\">, ", "LiteralC", - "<\"close-by-pushing\">]>; owner: ", + "<\"close-by-pushing\">]>; }>, ", + "TypeC", + "<{ owner: ", "StringC", - "; }>, ", + "; }>]>, ", "TypeC", "<{ created_at: ", "StringC", @@ -10019,6 +10005,8 @@ "<[", "IntersectionC", "<[", + "IntersectionC", + "<[", "TypeC", "<{ connector: ", "IntersectionC", @@ -10226,9 +10214,11 @@ "LiteralC", "<\"close-by-user\">, ", "LiteralC", - "<\"close-by-pushing\">]>; owner: ", + "<\"close-by-pushing\">]>; }>, ", + "TypeC", + "<{ owner: ", "StringC", - "; }>, ", + "; }>]>, ", "TypeC", "<{ created_at: ", "StringC", @@ -12728,7 +12718,7 @@ "IntersectionC", "<[", "PartialC", - ", ", "LiteralC", - "<\"close-by-pushing\">]>; owner: ", - "StringC", - "; }, \"connector\" | \"closure_type\">>, ", + "<\"close-by-pushing\">]>; }>, ", "TypeC", "<{ version: ", "StringC", @@ -12957,6 +12945,8 @@ "label": "CasesConfigureRequestRt", "description": [], "signature": [ + "IntersectionC", + "<[", "TypeC", "<{ connector: ", "IntersectionC", @@ -13164,9 +13154,11 @@ "LiteralC", "<\"close-by-user\">, ", "LiteralC", - "<\"close-by-pushing\">]>; owner: ", + "<\"close-by-pushing\">]>; }>, ", + "TypeC", + "<{ owner: ", "StringC", - "; }>" + "; }>]>" ], "source": { "path": "x-pack/plugins/cases/common/api/cases/configure.ts", diff --git a/api_docs/licensing.json b/api_docs/licensing.json index 6959c5fc0e5114..862a00e65215f4 100644 --- a/api_docs/licensing.json +++ b/api_docs/licensing.json @@ -3074,7 +3074,7 @@ "plugin": "security", "link": { "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 225 + "lineNumber": 229 } }, { diff --git a/api_docs/security.json b/api_docs/security.json index e0fd2a6bb33f2e..f7547221cec666 100644 --- a/api_docs/security.json +++ b/api_docs/security.json @@ -14,7 +14,13 @@ "\nRepresents the currently authenticated user." ], "signature": [ - "AuthenticatedUser", + { + "pluginId": "security", + "scope": "common", + "docId": "kibSecurityPluginApi", + "section": "def-common.AuthenticatedUser", + "text": "AuthenticatedUser" + }, " extends ", "User" ], @@ -120,7 +126,13 @@ ], "signature": [ "() => Promise<", - "AuthenticatedUser", + { + "pluginId": "security", + "scope": "common", + "docId": "kibSecurityPluginApi", + "section": "def-common.AuthenticatedUser", + "text": "AuthenticatedUser" + }, ">" ], "source": { @@ -943,6 +955,121 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "security", + "id": "def-server.AuditServiceSetup", + "type": "Interface", + "tags": [], + "label": "AuditServiceSetup", + "description": [], + "source": { + "path": "x-pack/plugins/security/server/audit/audit_service.ts", + "lineNumber": 40 + }, + "deprecated": false, + "children": [ + { + "parentPluginId": "security", + "id": "def-server.AuditServiceSetup.asScoped", + "type": "Function", + "tags": [], + "label": "asScoped", + "description": [], + "signature": [ + "(request: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreHttpPluginApi", + "section": "def-server.KibanaRequest", + "text": "KibanaRequest" + }, + ") => ", + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.AuditLogger", + "text": "AuditLogger" + } + ], + "source": { + "path": "x-pack/plugins/security/server/audit/audit_service.ts", + "lineNumber": 41 + }, + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "security", + "id": "def-server.request", + "type": "Object", + "tags": [], + "label": "request", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreHttpPluginApi", + "section": "def-server.KibanaRequest", + "text": "KibanaRequest" + }, + "" + ], + "source": { + "path": "x-pack/plugins/security/server/audit/audit_service.ts", + "lineNumber": 41 + }, + "deprecated": false + } + ] + }, + { + "parentPluginId": "security", + "id": "def-server.AuditServiceSetup.getLogger", + "type": "Function", + "tags": [], + "label": "getLogger", + "description": [], + "signature": [ + "(id?: string | undefined) => ", + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.LegacyAuditLogger", + "text": "LegacyAuditLogger" + } + ], + "source": { + "path": "x-pack/plugins/security/server/audit/audit_service.ts", + "lineNumber": 42 + }, + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "security", + "id": "def-server.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | undefined" + ], + "source": { + "path": "x-pack/plugins/security/server/audit/audit_service.ts", + "lineNumber": 42 + }, + "deprecated": false + } + ] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "security", "id": "def-server.AuthenticatedUser", @@ -953,7 +1080,13 @@ "\nRepresents the currently authenticated user." ], "signature": [ - "AuthenticatedUser", + { + "pluginId": "security", + "scope": "common", + "docId": "kibSecurityPluginApi", + "section": "def-common.AuthenticatedUser", + "text": "AuthenticatedUser" + }, " extends ", "User" ], @@ -1035,6 +1168,174 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "security", + "id": "def-server.AuthenticationServiceStart", + "type": "Interface", + "tags": [], + "label": "AuthenticationServiceStart", + "description": [ + "\nAuthentication services available on the security plugin's start contract." + ], + "source": { + "path": "x-pack/plugins/security/server/authentication/authentication_service.ts", + "lineNumber": 72 + }, + "deprecated": false, + "children": [ + { + "parentPluginId": "security", + "id": "def-server.AuthenticationServiceStart.apiKeys", + "type": "Object", + "tags": [], + "label": "apiKeys", + "description": [], + "signature": [ + "{ create: (request: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreHttpPluginApi", + "section": "def-server.KibanaRequest", + "text": "KibanaRequest" + }, + ", params: ", + "CreateAPIKeyParams", + ") => Promise<", + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.CreateAPIKeyResult", + "text": "CreateAPIKeyResult" + }, + " | null>; areAPIKeysEnabled: () => Promise; invalidate: (request: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreHttpPluginApi", + "section": "def-server.KibanaRequest", + "text": "KibanaRequest" + }, + ", params: ", + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.InvalidateAPIKeysParams", + "text": "InvalidateAPIKeysParams" + }, + ") => Promise<", + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.InvalidateAPIKeyResult", + "text": "InvalidateAPIKeyResult" + }, + " | null>; grantAsInternalUser: (request: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreHttpPluginApi", + "section": "def-server.KibanaRequest", + "text": "KibanaRequest" + }, + ", createParams: ", + "CreateAPIKeyParams", + ") => Promise<", + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.GrantAPIKeyResult", + "text": "GrantAPIKeyResult" + }, + " | null>; invalidateAsInternalUser: (params: ", + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.InvalidateAPIKeysParams", + "text": "InvalidateAPIKeysParams" + }, + ") => Promise<", + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.InvalidateAPIKeyResult", + "text": "InvalidateAPIKeyResult" + }, + " | null>; }" + ], + "source": { + "path": "x-pack/plugins/security/server/authentication/authentication_service.ts", + "lineNumber": 73 + }, + "deprecated": false + }, + { + "parentPluginId": "security", + "id": "def-server.AuthenticationServiceStart.getCurrentUser", + "type": "Function", + "tags": [], + "label": "getCurrentUser", + "description": [], + "signature": [ + "(request: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreHttpPluginApi", + "section": "def-server.KibanaRequest", + "text": "KibanaRequest" + }, + ") => ", + { + "pluginId": "security", + "scope": "common", + "docId": "kibSecurityPluginApi", + "section": "def-common.AuthenticatedUser", + "text": "AuthenticatedUser" + }, + " | null" + ], + "source": { + "path": "x-pack/plugins/security/server/authentication/authentication_service.ts", + "lineNumber": 81 + }, + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "security", + "id": "def-server.request", + "type": "Object", + "tags": [], + "label": "request", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreHttpPluginApi", + "section": "def-server.KibanaRequest", + "text": "KibanaRequest" + }, + "" + ], + "source": { + "path": "x-pack/plugins/security/server/authentication/authentication_service.ts", + "lineNumber": 81 + }, + "deprecated": false + } + ] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "security", "id": "def-server.CheckPrivilegesPayload", @@ -1496,385 +1797,484 @@ } ], "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "security", + "id": "def-server.AuthorizationServiceSetup", + "type": "Type", + "tags": [], + "label": "AuthorizationServiceSetup", + "description": [], + "source": { + "path": "x-pack/plugins/security/server/index.ts", + "lineNumber": 31 + }, + "deprecated": false, + "initialIsOpen": false }, { "parentPluginId": "security", - "id": "def-server.SecurityPluginSetup", - "type": "Interface", + "id": "def-server.ROUTE_TAG_CAN_REDIRECT", + "type": "string", "tags": [], - "label": "SecurityPluginSetup", + "label": "ROUTE_TAG_CAN_REDIRECT", "description": [ - "\nDescribes public Security plugin contract returned at the `setup` stage." + "\nIf the route is marked with this tag Security can safely assume that the calling party that sends\nrequest to this route can handle redirect responses. It's particularly important if we want the\nspecific route to be able to initiate or participate in the authentication handshake that may\ninvolve redirects and will eventually redirect authenticated user to this route." + ], + "signature": [ + "\"security:canRedirect\"" ], "source": { - "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 69 + "path": "x-pack/plugins/security/server/routes/tags.ts", + "lineNumber": 21 }, "deprecated": false, - "children": [ - { - "parentPluginId": "security", - "id": "def-server.SecurityPluginSetup.authc", - "type": "Object", - "tags": [ - "deprecated" - ], - "label": "authc", - "description": [], - "signature": [ - "{ getCurrentUser: (request: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.KibanaRequest", - "text": "KibanaRequest" - }, - ") => ", - "AuthenticatedUser", - " | null; }" - ], - "source": { - "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 73 + "initialIsOpen": false + } + ], + "objects": [], + "setup": { + "parentPluginId": "security", + "id": "def-server.SecurityPluginSetup", + "type": "Interface", + "tags": [], + "label": "SecurityPluginSetup", + "description": [ + "\nDescribes public Security plugin contract returned at the `setup` stage." + ], + "source": { + "path": "x-pack/plugins/security/server/plugin.ts", + "lineNumber": 72 + }, + "deprecated": false, + "children": [ + { + "parentPluginId": "security", + "id": "def-server.SecurityPluginSetup.authc", + "type": "Object", + "tags": [ + "deprecated" + ], + "label": "authc", + "description": [], + "signature": [ + "{ getCurrentUser: (request: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreHttpPluginApi", + "section": "def-server.KibanaRequest", + "text": "KibanaRequest" }, - "deprecated": true, - "references": [ - { - "plugin": "reporting", - "link": { - "path": "x-pack/plugins/reporting/server/routes/lib/get_user.ts", - "lineNumber": 13 - } - }, - { - "plugin": "encryptedSavedObjects", - "link": { - "path": "x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.ts", - "lineNumber": 107 - } - }, - { - "plugin": "encryptedSavedObjects", - "link": { - "path": "x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.ts", - "lineNumber": 67 - } - }, - { - "plugin": "actions", - "link": { - "path": "x-pack/plugins/actions/server/plugin.ts", - "lineNumber": 444 - } - }, - { - "plugin": "ml", - "link": { - "path": "x-pack/plugins/ml/server/routes/annotations.ts", - "lineNumber": 105 - } - }, - { - "plugin": "dashboardMode", - "link": { - "path": "x-pack/plugins/dashboard_mode/server/interceptors/dashboard_mode_request_interceptor.ts", - "lineNumber": 33 - } - }, - { - "plugin": "dataEnhanced", - "link": { - "path": "x-pack/plugins/data_enhanced/server/search/session/session_service.ts", - "lineNumber": 448 - } - }, - { - "plugin": "logstash", - "link": { - "path": "x-pack/plugins/logstash/server/routes/pipeline/save.ts", - "lineNumber": 41 - } - }, - { - "plugin": "securitySolution", - "link": { - "path": "x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts", - "lineNumber": 48 - } - }, - { - "plugin": "securitySolution", - "link": { - "path": "x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts", - "lineNumber": 45 - } - }, - { - "plugin": "securitySolution", - "link": { - "path": "x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts", - "lineNumber": 45 - } - }, - { - "plugin": "securitySolution", - "link": { - "path": "x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts", - "lineNumber": 28 - } + ") => ", + { + "pluginId": "security", + "scope": "common", + "docId": "kibSecurityPluginApi", + "section": "def-common.AuthenticatedUser", + "text": "AuthenticatedUser" + }, + " | null; }" + ], + "source": { + "path": "x-pack/plugins/security/server/plugin.ts", + "lineNumber": 76 + }, + "deprecated": true, + "references": [ + { + "plugin": "reporting", + "link": { + "path": "x-pack/plugins/reporting/server/routes/lib/get_user.ts", + "lineNumber": 13 } - ] + }, + { + "plugin": "encryptedSavedObjects", + "link": { + "path": "x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.ts", + "lineNumber": 107 + } + }, + { + "plugin": "encryptedSavedObjects", + "link": { + "path": "x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.ts", + "lineNumber": 67 + } + }, + { + "plugin": "actions", + "link": { + "path": "x-pack/plugins/actions/server/plugin.ts", + "lineNumber": 444 + } + }, + { + "plugin": "ml", + "link": { + "path": "x-pack/plugins/ml/server/routes/annotations.ts", + "lineNumber": 105 + } + }, + { + "plugin": "dashboardMode", + "link": { + "path": "x-pack/plugins/dashboard_mode/server/interceptors/dashboard_mode_request_interceptor.ts", + "lineNumber": 33 + } + }, + { + "plugin": "dataEnhanced", + "link": { + "path": "x-pack/plugins/data_enhanced/server/search/session/session_service.ts", + "lineNumber": 448 + } + }, + { + "plugin": "logstash", + "link": { + "path": "x-pack/plugins/logstash/server/routes/pipeline/save.ts", + "lineNumber": 41 + } + }, + { + "plugin": "securitySolution", + "link": { + "path": "x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts", + "lineNumber": 48 + } + }, + { + "plugin": "securitySolution", + "link": { + "path": "x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts", + "lineNumber": 45 + } + }, + { + "plugin": "securitySolution", + "link": { + "path": "x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts", + "lineNumber": 45 + } + }, + { + "plugin": "securitySolution", + "link": { + "path": "x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts", + "lineNumber": 28 + } + } + ] + }, + { + "parentPluginId": "security", + "id": "def-server.SecurityPluginSetup.authz", + "type": "Object", + "tags": [ + "deprecated" + ], + "label": "authz", + "description": [], + "signature": [ + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.AuthorizationServiceSetup", + "text": "AuthorizationServiceSetup" + } + ], + "source": { + "path": "x-pack/plugins/security/server/plugin.ts", + "lineNumber": 80 }, - { - "parentPluginId": "security", - "id": "def-server.SecurityPluginSetup.authz", - "type": "Object", - "tags": [ - "deprecated" - ], - "label": "authz", - "description": [], - "signature": [ - "{ mode: ", - "AuthorizationMode", - "; actions: ", - "Actions", - "; checkPrivilegesDynamicallyWithRequest: ", - "CheckPrivilegesDynamicallyWithRequest", - "; checkPrivilegesWithRequest: ", - "CheckPrivilegesWithRequest", - "; }" - ], - "source": { - "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 77 + "deprecated": true, + "references": [ + { + "plugin": "actions", + "link": { + "path": "x-pack/plugins/actions/server/plugin.ts", + "lineNumber": 443 + } }, - "deprecated": true, - "references": [ - { - "plugin": "actions", - "link": { - "path": "x-pack/plugins/actions/server/plugin.ts", - "lineNumber": 443 - } - }, - { - "plugin": "ml", - "link": { - "path": "x-pack/plugins/ml/server/saved_objects/initialization/initialization.ts", - "lineNumber": 54 - } - }, - { - "plugin": "ml", - "link": { - "path": "x-pack/plugins/ml/server/plugin.ts", - "lineNumber": 153 - } - }, - { - "plugin": "ml", - "link": { - "path": "x-pack/plugins/ml/server/plugin.ts", - "lineNumber": 203 - } - }, - { - "plugin": "enterpriseSearch", - "link": { - "path": "x-pack/plugins/enterprise_search/server/lib/check_access.ts", - "lineNumber": 46 - } - }, - { - "plugin": "enterpriseSearch", - "link": { - "path": "x-pack/plugins/enterprise_search/server/lib/check_access.ts", - "lineNumber": 86 - } - }, - { - "plugin": "enterpriseSearch", - "link": { - "path": "x-pack/plugins/enterprise_search/server/lib/check_access.ts", - "lineNumber": 88 - } - }, - { - "plugin": "savedObjectsTagging", - "link": { - "path": "x-pack/plugins/saved_objects_tagging/server/request_handler_context.ts", - "lineNumber": 37 - } + { + "plugin": "ml", + "link": { + "path": "x-pack/plugins/ml/server/saved_objects/initialization/initialization.ts", + "lineNumber": 54 } - ] + }, + { + "plugin": "ml", + "link": { + "path": "x-pack/plugins/ml/server/plugin.ts", + "lineNumber": 153 + } + }, + { + "plugin": "ml", + "link": { + "path": "x-pack/plugins/ml/server/plugin.ts", + "lineNumber": 203 + } + }, + { + "plugin": "enterpriseSearch", + "link": { + "path": "x-pack/plugins/enterprise_search/server/lib/check_access.ts", + "lineNumber": 46 + } + }, + { + "plugin": "enterpriseSearch", + "link": { + "path": "x-pack/plugins/enterprise_search/server/lib/check_access.ts", + "lineNumber": 86 + } + }, + { + "plugin": "enterpriseSearch", + "link": { + "path": "x-pack/plugins/enterprise_search/server/lib/check_access.ts", + "lineNumber": 88 + } + }, + { + "plugin": "savedObjectsTagging", + "link": { + "path": "x-pack/plugins/saved_objects_tagging/server/request_handler_context.ts", + "lineNumber": 37 + } + } + ] + }, + { + "parentPluginId": "security", + "id": "def-server.SecurityPluginSetup.license", + "type": "Object", + "tags": [], + "label": "license", + "description": [ + "\nExposes information about the available security features under the current license." + ], + "signature": [ + { + "pluginId": "security", + "scope": "common", + "docId": "kibSecurityPluginApi", + "section": "def-common.SecurityLicense", + "text": "SecurityLicense" + } + ], + "source": { + "path": "x-pack/plugins/security/server/plugin.ts", + "lineNumber": 84 }, + "deprecated": false + }, + { + "parentPluginId": "security", + "id": "def-server.SecurityPluginSetup.audit", + "type": "Object", + "tags": [], + "label": "audit", + "description": [ + "\nExposes services for audit logging." + ], + "signature": [ + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.AuditServiceSetup", + "text": "AuditServiceSetup" + } + ], + "source": { + "path": "x-pack/plugins/security/server/plugin.ts", + "lineNumber": 88 + }, + "deprecated": false + } + ], + "lifecycle": "setup", + "initialIsOpen": true + }, + "start": { + "parentPluginId": "security", + "id": "def-server.SecurityPluginStart", + "type": "Interface", + "tags": [], + "label": "SecurityPluginStart", + "description": [ + "\nDescribes public Security plugin contract returned at the `start` stage." + ], + "source": { + "path": "x-pack/plugins/security/server/plugin.ts", + "lineNumber": 94 + }, + "deprecated": false, + "children": [ + { + "parentPluginId": "security", + "id": "def-server.SecurityPluginStart.authc", + "type": "Object", + "tags": [], + "label": "authc", + "description": [ + "\nAuthentication services to confirm the user is who they say they are." + ], + "signature": [ + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.AuthenticationServiceStart", + "text": "AuthenticationServiceStart" + } + ], + "source": { + "path": "x-pack/plugins/security/server/plugin.ts", + "lineNumber": 98 + }, + "deprecated": false + }, + { + "parentPluginId": "security", + "id": "def-server.SecurityPluginStart.authz", + "type": "Object", + "tags": [], + "label": "authz", + "description": [ + "\nAuthorization services to manage and access the permissions a particular user has." + ], + "signature": [ + { + "pluginId": "security", + "scope": "server", + "docId": "kibSecurityPluginApi", + "section": "def-server.AuthorizationServiceSetup", + "text": "AuthorizationServiceSetup" + } + ], + "source": { + "path": "x-pack/plugins/security/server/plugin.ts", + "lineNumber": 102 + }, + "deprecated": false + } + ], + "lifecycle": "start", + "initialIsOpen": true + } + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [ + { + "parentPluginId": "security", + "id": "def-common.AuthenticatedUser", + "type": "Interface", + "tags": [], + "label": "AuthenticatedUser", + "description": [ + "\nRepresents the currently authenticated user." + ], + "signature": [ + { + "pluginId": "security", + "scope": "common", + "docId": "kibSecurityPluginApi", + "section": "def-common.AuthenticatedUser", + "text": "AuthenticatedUser" + }, + " extends ", + "User" + ], + "source": { + "path": "x-pack/plugins/security/common/model/authenticated_user.ts", + "lineNumber": 21 + }, + "deprecated": false, + "children": [ { "parentPluginId": "security", - "id": "def-server.SecurityPluginSetup.license", + "id": "def-common.AuthenticatedUser.authentication_realm", "type": "Object", "tags": [], - "label": "license", - "description": [], + "label": "authentication_realm", + "description": [ + "\nThe name and type of the Realm that has authenticated the user." + ], "signature": [ - { - "pluginId": "security", - "scope": "common", - "docId": "kibSecurityPluginApi", - "section": "def-common.SecurityLicense", - "text": "SecurityLicense" - } + "UserRealm" ], "source": { - "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 81 + "path": "x-pack/plugins/security/common/model/authenticated_user.ts", + "lineNumber": 25 }, "deprecated": false }, { "parentPluginId": "security", - "id": "def-server.SecurityPluginSetup.audit", + "id": "def-common.AuthenticatedUser.lookup_realm", "type": "Object", "tags": [], - "label": "audit", - "description": [], + "label": "lookup_realm", + "description": [ + "\nThe name and type of the Realm where the user information were retrieved from." + ], "signature": [ - "AuditServiceSetup" + "UserRealm" ], "source": { - "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 82 + "path": "x-pack/plugins/security/common/model/authenticated_user.ts", + "lineNumber": 30 }, "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "security", - "id": "def-server.SecurityPluginStart", - "type": "Interface", - "tags": [], - "label": "SecurityPluginStart", - "description": [ - "\nDescribes public Security plugin contract returned at the `start` stage." - ], - "source": { - "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 88 - }, - "deprecated": false, - "children": [ + }, { "parentPluginId": "security", - "id": "def-server.SecurityPluginStart.authc", + "id": "def-common.AuthenticatedUser.authentication_provider", "type": "Object", "tags": [], - "label": "authc", - "description": [], + "label": "authentication_provider", + "description": [ + "\nThe authentication provider that used to authenticate user." + ], "signature": [ - "{ getCurrentUser: (request: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.KibanaRequest", - "text": "KibanaRequest" - }, - ") => ", - "AuthenticatedUser", - " | null; apiKeys: Pick<", - "APIKeys", - ", \"create\" | \"areAPIKeysEnabled\" | \"invalidate\" | \"grantAsInternalUser\" | \"invalidateAsInternalUser\">; }" + "AuthenticationProvider" ], "source": { - "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 89 + "path": "x-pack/plugins/security/common/model/authenticated_user.ts", + "lineNumber": 35 }, "deprecated": false }, { "parentPluginId": "security", - "id": "def-server.SecurityPluginStart.authz", - "type": "Object", + "id": "def-common.AuthenticatedUser.authentication_type", + "type": "string", "tags": [], - "label": "authz", - "description": [], - "signature": [ - "{ mode: ", - "AuthorizationMode", - "; actions: ", - "Actions", - "; checkPrivilegesDynamicallyWithRequest: ", - "CheckPrivilegesDynamicallyWithRequest", - "; checkPrivilegesWithRequest: ", - "CheckPrivilegesWithRequest", - "; }" + "label": "authentication_type", + "description": [ + "\nThe AuthenticationType used by ES to authenticate the user.\n" ], "source": { - "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 90 + "path": "x-pack/plugins/security/common/model/authenticated_user.ts", + "lineNumber": 42 }, "deprecated": false } ], "initialIsOpen": false - } - ], - "enums": [], - "misc": [ - { - "parentPluginId": "security", - "id": "def-server.AuthorizationServiceSetup", - "type": "Type", - "tags": [], - "label": "AuthorizationServiceSetup", - "description": [], - "signature": [ - "{ mode: ", - "AuthorizationMode", - "; actions: ", - "Actions", - "; checkPrivilegesDynamicallyWithRequest: ", - "CheckPrivilegesDynamicallyWithRequest", - "; checkPrivilegesWithRequest: ", - "CheckPrivilegesWithRequest", - "; }" - ], - "source": { - "path": "x-pack/plugins/security/server/index.ts", - "lineNumber": 30 - }, - "deprecated": false, - "initialIsOpen": false }, - { - "parentPluginId": "security", - "id": "def-server.ROUTE_TAG_CAN_REDIRECT", - "type": "string", - "tags": [], - "label": "ROUTE_TAG_CAN_REDIRECT", - "description": [ - "\nIf the route is marked with this tag Security can safely assume that the calling party that sends\nrequest to this route can handle redirect responses. It's particularly important if we want the\nspecific route to be able to initiate or participate in the authentication handshake that may\ninvolve redirects and will eventually redirect authenticated user to this route." - ], - "signature": [ - "\"security:canRedirect\"" - ], - "source": { - "path": "x-pack/plugins/security/server/routes/tags.ts", - "lineNumber": 21 - }, - "deprecated": false, - "initialIsOpen": false - } - ], - "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [ { "parentPluginId": "security", "id": "def-common.SecurityLicense", diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 07f219ce6e7715..250ceff429207b 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -27,6 +27,12 @@ import securityObj from './security.json'; ## Server +### Setup + + +### Start + + ### Interfaces diff --git a/api_docs/spaces.json b/api_docs/spaces.json index d24b3884ffac6f..002145f3b48db6 100644 --- a/api_docs/spaces.json +++ b/api_docs/spaces.json @@ -1203,7 +1203,7 @@ "plugin": "security", "link": { "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 263 + "lineNumber": 267 } }, { @@ -2002,28 +2002,28 @@ "plugin": "security", "link": { "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 57 + "lineNumber": 60 } }, { "plugin": "security", "link": { "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 263 + "lineNumber": 267 } }, { "plugin": "security", "link": { "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 281 + "lineNumber": 285 } }, { "plugin": "security", "link": { "path": "x-pack/plugins/security/server/plugin.ts", - "lineNumber": 297 + "lineNumber": 301 } }, { diff --git a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/ServicePage/ServicePage.tsx b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/ServicePage/ServicePage.tsx index 71355a84d28d49..d71751805ce416 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/ServicePage/ServicePage.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/ServicePage/ServicePage.tsx @@ -5,14 +5,7 @@ * 2.0. */ -import { - EuiTitle, - EuiSpacer, - EuiPanel, - EuiFlexGroup, - EuiFlexItem, - EuiButton, -} from '@elastic/eui'; +import { EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui'; import React from 'react'; import { i18n } from '@kbn/i18n'; import { isString } from 'lodash'; @@ -100,17 +93,7 @@ export function ServicePage({ newConfig, setNewConfig, onClickNext }: Props) { ); return ( - - -

- {i18n.translate('xpack.apm.agentConfig.servicePage.title', { - defaultMessage: 'Choose service', - })} -

-
- - - + <> {/* Service name options */} -
+ ); } diff --git a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/SettingsPage/SettingsPage.tsx b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/SettingsPage/SettingsPage.tsx index b26779c5fe9491..7623e467aaa2d1 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/SettingsPage/SettingsPage.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/SettingsPage/SettingsPage.tsx @@ -15,11 +15,10 @@ import { EuiForm, EuiHealth, EuiLoadingSpinner, - EuiPanel, EuiSpacer, EuiStat, EuiText, - EuiTitle, + EuiHorizontalRule, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useMemo, useState } from 'react'; @@ -136,79 +135,55 @@ export function SettingsPage({ }} > {/* Selected Service panel */} - - -

- {i18n.translate('xpack.apm.agentConfig.chooseService.title', { - defaultMessage: 'Choose service', - })} -

-
- - - - - - - - - - - {!isEditMode && ( - - {i18n.translate( - 'xpack.apm.agentConfig.chooseService.editButton', - { defaultMessage: 'Edit' } - )} - + + + + + + - -
+ /> + + + {!isEditMode && ( + + {i18n.translate( + 'xpack.apm.agentConfig.chooseService.editButton', + { defaultMessage: 'Edit' } + )} + + )} + + - + {/* Settings panel */} - - -

- {i18n.translate('xpack.apm.agentConfig.settings.title', { - defaultMessage: 'Configuration options', - })} -

-
- - - {isLoading ? ( -
- -
- ) : ( - renderSettings({ unsavedChanges, newConfig, setNewConfig }) - )} -
+ {isLoading ? ( +
+ +
+ ) : ( + renderSettings({ unsavedChanges, newConfig, setNewConfig }) + )} diff --git a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx index 07afb2fece283e..a0ca7daf826106 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx @@ -109,7 +109,15 @@ export function AgentConfigurationCreateEdit({ return ( <> - + + {i18n.translate('xpack.apm.agentConfig.newConfig.description', { + defaultMessage: `Fine-tune your agent configuration from within the APM app. Changes are automatically propagated to your APM agents, so there’s no need to redeploy.`, + })} + + + + +

{isEditMode ? i18n.translate('xpack.apm.agentConfig.editConfigTitle', { @@ -121,12 +129,6 @@ export function AgentConfigurationCreateEdit({

- - {i18n.translate('xpack.apm.agentConfig.newConfig.description', { - defaultMessage: `Fine-tune your agent configuration from within the APM app. Changes are automatically propagated to your APM agents, so there’s no need to redeploy.`, - })} - - {pageStep === 'choose-service-step' && ( diff --git a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/index.tsx index b781a6569cc359..1ca7f46a0b26fa 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/index.tsx @@ -10,7 +10,6 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem, - EuiPanel, EuiSpacer, EuiTitle, EuiText, @@ -42,44 +41,36 @@ export function AgentConfigurations() { return ( <> - -

- {i18n.translate('xpack.apm.agentConfig.titleText', { - defaultMessage: 'Agent central configuration', - })} -

-
- {i18n.translate('xpack.apm.settings.agentConfig.descriptionText', { defaultMessage: `Fine-tune your agent configuration from within the APM app. Changes are automatically propagated to your APM agents, so there’s no need to redeploy.`, })} - - - - - -

- {i18n.translate( - 'xpack.apm.agentConfig.configurationsPanelTitle', - { defaultMessage: 'Configurations' } - )} -

-
-
- {hasConfigurations ? : null} -
+ - + + + +

+ {i18n.translate( + 'xpack.apm.agentConfig.configurationsPanelTitle', + { defaultMessage: 'Configurations' } + )} +

+
+
+ + {hasConfigurations ? : null} +
+ + - -
+ ); } diff --git a/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.test.tsx b/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.test.tsx index 28cb4ebd51cddc..1b19bb5860b2c7 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.test.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.test.tsx @@ -26,7 +26,7 @@ describe('ApmIndices', () => { expect(getByText('Indices')).toMatchInlineSnapshot(`

Indices

diff --git a/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx index 44a3c4655417cf..2d74187f9d83b9 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx @@ -13,7 +13,6 @@ import { EuiFlexItem, EuiForm, EuiFormRow, - EuiPanel, EuiSpacer, EuiText, EuiTitle, @@ -176,100 +175,101 @@ export function ApmIndices() { return ( <> - + + {i18n.translate('xpack.apm.settings.apmIndices.description', { + defaultMessage: `The APM UI uses index patterns to query your APM indices. If you've customized the index names that APM Server writes events to, you may need to update these patterns for the APM UI to work. Settings here take precedence over those set in kibana.yml.`, + })} + + + + +

{i18n.translate('xpack.apm.settings.apmIndices.title', { defaultMessage: 'Indices', })}

- - - {i18n.translate('xpack.apm.settings.apmIndices.description', { - defaultMessage: `The APM UI uses index patterns to query your APM indices. If you've customized the index names that APM Server writes events to, you may need to update these patterns for the APM UI to work. Settings here take precedence over those set in kibana.yml.`, - })} - - - - - - - {APM_INDEX_LABELS.map(({ configurationName, label }) => { - const matchedConfiguration = data.apmIndexSettings.find( - ({ configurationName: configName }) => - configName === configurationName - ); - const defaultValue = matchedConfiguration - ? matchedConfiguration.defaultValue - : ''; - const savedUiIndexValue = apmIndices[configurationName] || ''; - return ( - + + + + + {APM_INDEX_LABELS.map(({ configurationName, label }) => { + const matchedConfiguration = data.apmIndexSettings.find( + ({ configurationName: configName }) => + configName === configurationName + ); + const defaultValue = matchedConfiguration + ? matchedConfiguration.defaultValue + : ''; + const savedUiIndexValue = apmIndices[configurationName] || ''; + return ( + + + + ); + })} + + + + + {i18n.translate( + 'xpack.apm.settings.apmIndices.cancelButton', + { defaultMessage: 'Cancel' } + )} + + + + + - - - ); - })} - - - - {i18n.translate( - 'xpack.apm.settings.apmIndices.cancelButton', - { defaultMessage: 'Cancel' } + 'xpack.apm.settings.apmIndices.applyButton', + { defaultMessage: 'Apply changes' } )} - - - - - - {i18n.translate( - 'xpack.apm.settings.apmIndices.applyButton', - { defaultMessage: 'Apply changes' } - )} - - - - - - - - - + + + + + + + ); } diff --git a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/index.tsx index ab18a31e769172..c1315f165abdb2 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/index.tsx @@ -8,7 +8,6 @@ import { EuiFlexGroup, EuiFlexItem, - EuiPanel, EuiTitle, EuiText, EuiSpacer, @@ -83,62 +82,51 @@ export function CustomLinkOverview() { }} /> )} - - - - + + + {i18n.translate('xpack.apm.settings.customizeUI.customLink.info', { + defaultMessage: + 'These links will be shown in the Actions context menu in selected areas of the app, e.g. by the transactions detail.', + })} + + + + + + + +

+ {i18n.translate('xpack.apm.settings.customizeUI.customLink', { + defaultMessage: 'Custom Links', + })} +

+
+
+ {hasValidLicense && !showEmptyPrompt && ( + + - - - -

- {i18n.translate( - 'xpack.apm.settings.customizeUI.customLink', - { - defaultMessage: 'Custom Links', - } - )} -

-
-
-
+
- {hasValidLicense && !showEmptyPrompt && ( - - - - - - - - )} -
- - - {i18n.translate('xpack.apm.settings.customizeUI.customLink.info', { - defaultMessage: - 'These links will be shown in the Actions context menu in selected areas of the app, e.g. by the transactions detail.', - })} - - {hasValidLicense ? ( - showEmptyPrompt ? ( - - ) : ( - - ) - ) : ( - )} -
+ + + + + {hasValidLicense ? ( + showEmptyPrompt ? ( + + ) : ( + + ) + ) : ( + + )} ); } diff --git a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/index.tsx index c4b3c39248ffbf..9ce1f1325bb2c4 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/index.tsx @@ -6,28 +6,8 @@ */ import React from 'react'; -import { EuiTitle, EuiSpacer, EuiText } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import { CustomLinkOverview } from './CustomLink'; export function CustomizeUI() { - return ( - <> - -

- {i18n.translate('xpack.apm.settings.customizeApp.title', { - defaultMessage: 'Customize app', - })} -

-
- - - {i18n.translate('xpack.apm.settings.customizeApp.description', { - defaultMessage: `Extend the APM app experience with the following settings.`, - })} - - - - - ); + return ; } diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/add_environments.tsx b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/add_environments.tsx index bf9062418313ad..89e5dfcbdadfb7 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/add_environments.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/add_environments.tsx @@ -7,7 +7,6 @@ import React, { useState } from 'react'; import { - EuiPanel, EuiTitle, EuiText, EuiSpacer, @@ -70,29 +69,27 @@ export function AddEnvironments({ if (!canCreateJob) { return ( - - {ML_ERRORS.MISSING_WRITE_PRIVILEGES}} - /> - + {ML_ERRORS.MISSING_WRITE_PRIVILEGES}} + /> ); } const isLoading = status === FETCH_STATUS.LOADING; return ( - - + <> +

{i18n.translate( 'xpack.apm.settings.anomalyDetection.addEnvironments.titleText', - { - defaultMessage: 'Select environments', - } + { defaultMessage: 'Select environments' } )}

+ + {i18n.translate( 'xpack.apm.settings.anomalyDetection.addEnvironments.descriptionText', @@ -181,6 +178,6 @@ export function AddEnvironments({ -
+ ); } diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/index.tsx index 38b9970f64d32c..57d141d763909b 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/index.tsx @@ -6,8 +6,6 @@ */ import React, { useState } from 'react'; -import { EuiTitle, EuiSpacer, EuiText } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import { EuiPanel, EuiEmptyPrompt } from '@elastic/eui'; import { ML_ERRORS } from '../../../../../common/anomaly_detection'; import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context'; @@ -66,20 +64,6 @@ export function AnomalyDetection() { return ( <> - -

- {i18n.translate('xpack.apm.settings.anomalyDetection.titleText', { - defaultMessage: 'Anomaly detection', - })} -

-
- - - {i18n.translate('xpack.apm.settings.anomalyDetection.descriptionText', { - defaultMessage: `Machine Learning's anomaly detection integration enables application health status indicators for services in each configured environment by identifying anomalies in latency.`, - })} - - {viewAddEnvironments ? ( environment)} diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx index 9c69d692876b0a..6df2ed73afe76a 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx @@ -9,7 +9,6 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem, - EuiPanel, EuiSpacer, EuiText, EuiTitle, @@ -66,7 +65,28 @@ export function JobsList({ data, status, onAddEnvironments }: Props) { const { jobs, hasLegacyJobs } = data; return ( - + <> + + + {i18n.translate( + 'xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText.mlJobsLinkText', + { + defaultMessage: 'Machine Learning', + } + )} + + ), + }} + /> + + + + @@ -91,25 +111,9 @@ export function JobsList({ data, status, onAddEnvironments }: Props) { - - - {i18n.translate( - 'xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText.mlJobsLinkText', - { - defaultMessage: 'Machine Learning', - } - )} - - ), - }} - /> - - + + + {hasLegacyJobs && } - + ); } diff --git a/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx b/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx index 09c25ee4557c56..3d530f4614d82d 100644 --- a/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx +++ b/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx @@ -219,41 +219,33 @@ function TransactionDetailsRouteView( function SettingsAgentConfigurationRouteView() { return ( - - - - - + + + ); } function SettingsAnomalyDetectionRouteView() { return ( - - - - - + + + ); } function SettingsApmIndicesRouteView() { return ( - - - - - + + + ); } function SettingsCustomizeUI() { return ( - - - - - + + + ); } @@ -276,14 +268,12 @@ export function EditAgentConfigurationRouteView(props: RouteComponentProps) { ); return ( - - - - - + + + ); } @@ -295,13 +285,11 @@ export function CreateAgentConfigurationRouteView(props: RouteComponentProps) { const { pageStep } = toQuery(search); return ( - - - - - + + + ); } diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx index e917350f6024bf..357ba4c3d9f386 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx @@ -31,6 +31,7 @@ export function ApmMainTemplate({ children: React.ReactNode; } & EuiPageTemplateProps) { const { services } = useKibana(); + const ObservabilityPageTemplate = services.observability.navigation.PageTemplate; diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template.tsx index ab53052780ea9a..bbaffbd3374c6c 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template.tsx @@ -33,23 +33,21 @@ import { Correlations } from '../../app/correlations'; import { SearchBar } from '../../shared/search_bar'; type Tab = NonNullable[0] & { - key: string; + key: + | 'errors' + | 'metrics' + | 'nodes' + | 'overview' + | 'service-map' + | 'profiling' + | 'transactions'; hidden?: boolean; }; -type TabKey = - | 'errors' - | 'metrics' - | 'nodes' - | 'overview' - | 'service-map' - | 'profiling' - | 'transactions'; - interface Props { children: React.ReactNode; serviceName: string; - selectedTab: TabKey; + selectedTab: Tab['key']; searchBarOptions?: React.ComponentProps; } @@ -107,7 +105,7 @@ function useTabs({ selectedTab, }: { serviceName: string; - selectedTab: TabKey; + selectedTab: Tab['key']; }) { const { agentName, transactionType } = useApmServiceContext(); const { core, config } = useApmPluginContext(); diff --git a/x-pack/plugins/apm/public/components/routing/templates/settings_template.test.tsx b/x-pack/plugins/apm/public/components/routing/templates/settings_template.test.tsx index 36d54525d2537b..d3efef4c883803 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/settings_template.test.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/settings_template.test.tsx @@ -11,13 +11,28 @@ import React, { ReactNode } from 'react'; import { SettingsTemplate } from './settings_template'; import { createMemoryHistory } from 'history'; import { MemoryRouter, RouteComponentProps } from 'react-router-dom'; +import { CoreStart } from 'kibana/public'; +import { createKibanaReactContext } from 'src/plugins/kibana_react/public'; const { location } = createMemoryHistory(); +const KibanaReactContext = createKibanaReactContext({ + usageCollection: { reportUiCounter: () => {} }, + observability: { + navigation: { + PageTemplate: () => { + return <>hello world; + }, + }, + }, +} as Partial); + function Wrapper({ children }: { children?: ReactNode }) { return ( - {children} + + {children} + ); } @@ -29,8 +44,8 @@ describe('Settings', () => { } as unknown) as RouteComponentProps<{}>; expect(() => render( - -
+ +
hello world
, { wrapper: Wrapper } ) diff --git a/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx index 66958c01a7fea1..0e610722a76e7e 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx @@ -5,90 +5,108 @@ * 2.0. */ -import { EuiPage, EuiPageBody, EuiPageSideBar, EuiSideNav } from '@elastic/eui'; +import { EuiPageHeaderProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { ReactNode, useState } from 'react'; +import React from 'react'; +import { History } from 'history'; import { useHistory } from 'react-router-dom'; +import { CoreStart } from 'kibana/public'; +import { ApmMainTemplate } from './apm_main_template'; import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context'; import { getAPMHref } from '../../shared/Links/apm/APMLink'; -export function SettingsTemplate({ children }: { children: ReactNode }) { +type Tab = NonNullable[0] & { + key: + | 'agent-configurations' + | 'anomaly-detection' + | 'apm-indices' + | 'customize-ui'; + hidden?: boolean; +}; + +interface Props { + children: React.ReactNode; + selectedTab: Tab['key']; +} + +export function SettingsTemplate({ children, selectedTab }: Props) { const { core } = useApmPluginContext(); const history = useHistory(); - const { basePath } = core.http; - const canAccessML = !!core.application.capabilities.ml?.canAccessML; - const { search, pathname } = history.location; + const tabs = getTabs({ history, core, selectedTab }); - const [isSideNavOpenOnMobile, setisSideNavOpenOnMobile] = useState(false); + return ( + + {children} + + ); +} - const toggleOpenOnMobile = () => { - setisSideNavOpenOnMobile((prevState) => !prevState); - }; +function getTabs({ + history, + core, + selectedTab, +}: { + history: History; + core: CoreStart; + selectedTab: Tab['key']; +}) { + const { basePath } = core.http; + const canAccessML = !!core.application.capabilities.ml?.canAccessML; + const { search } = history.location; - function getSettingsHref(path: string) { - return getAPMHref({ basePath, path: `/settings${path}`, search }); - } + const tabs: Tab[] = [ + { + key: 'agent-configurations', + label: i18n.translate('xpack.apm.settings.agentConfig', { + defaultMessage: 'Agent Configuration', + }), + href: getAPMHref({ + basePath, + path: `/settings/agent-configuration`, + search, + }), + }, + { + key: 'anomaly-detection', + label: i18n.translate('xpack.apm.settings.anomalyDetection', { + defaultMessage: 'Anomaly detection', + }), + href: getAPMHref({ + basePath, + path: `/settings/anomaly-detection`, + search, + }), + hidden: !canAccessML, + }, + { + key: 'customize-ui', + label: i18n.translate('xpack.apm.settings.customizeApp', { + defaultMessage: 'Customize app', + }), + href: getAPMHref({ basePath, path: `/settings/customize-ui`, search }), + }, + { + key: 'apm-indices', + label: i18n.translate('xpack.apm.settings.indices', { + defaultMessage: 'Indices', + }), + href: getAPMHref({ basePath, path: `/settings/apm-indices`, search }), + }, + ]; - return ( - - - toggleOpenOnMobile()} - isOpenOnMobile={isSideNavOpenOnMobile} - items={[ - { - name: i18n.translate('xpack.apm.settings.pageTitle', { - defaultMessage: 'Settings', - }), - id: 0, - items: [ - { - name: i18n.translate('xpack.apm.settings.agentConfig', { - defaultMessage: 'Agent Configuration', - }), - id: '1', - href: getSettingsHref('/agent-configuration'), - isSelected: pathname.startsWith( - '/settings/agent-configuration' - ), - }, - ...(canAccessML - ? [ - { - name: i18n.translate( - 'xpack.apm.settings.anomalyDetection', - { - defaultMessage: 'Anomaly detection', - } - ), - id: '4', - href: getSettingsHref('/anomaly-detection'), - isSelected: pathname === '/settings/anomaly-detection', - }, - ] - : []), - { - name: i18n.translate('xpack.apm.settings.customizeApp', { - defaultMessage: 'Customize app', - }), - id: '3', - href: getSettingsHref('/customize-ui'), - isSelected: pathname === '/settings/customize-ui', - }, - { - name: i18n.translate('xpack.apm.settings.indices', { - defaultMessage: 'Indices', - }), - id: '2', - href: getSettingsHref('/apm-indices'), - isSelected: pathname === '/settings/apm-indices', - }, - ], - }, - ]} - /> - - {children} - - ); + return tabs + .filter((t) => !t.hidden) + .map(({ href, key, label }) => ({ + href, + label, + isSelected: key === selectedTab, + })); } diff --git a/x-pack/plugins/apm/public/plugin.ts b/x-pack/plugins/apm/public/plugin.ts index 24db9e0cd8504f..bfc0a3daf6f0ed 100644 --- a/x-pack/plugins/apm/public/plugin.ts +++ b/x-pack/plugins/apm/public/plugin.ts @@ -6,7 +6,8 @@ */ import { i18n } from '@kbn/i18n'; -import { of } from 'rxjs'; +import { from } from 'rxjs'; +import { map } from 'rxjs/operators'; import type { ConfigSchema } from '.'; import { AppMountParameters, @@ -86,19 +87,56 @@ export class ApmPlugin implements Plugin { pluginSetupDeps.home.featureCatalogue.register(featureCatalogueEntry); } - // register observability nav + const servicesTitle = i18n.translate('xpack.apm.navigation.servicesTitle', { + defaultMessage: 'Services', + }); + const tracesTitle = i18n.translate('xpack.apm.navigation.tracesTitle', { + defaultMessage: 'Traces', + }); + const serviceMapTitle = i18n.translate( + 'xpack.apm.navigation.serviceMapTitle', + { defaultMessage: 'Service Map' } + ); + + // register observability nav if user has access to plugin plugins.observability.navigation.registerSections( - of([ - { - label: 'APM', - sortKey: 200, - entries: [ - { label: 'Services', app: 'apm', path: '/services' }, - { label: 'Traces', app: 'apm', path: '/traces' }, - { label: 'Service Map', app: 'apm', path: '/service-map' }, - ], - }, - ]) + from(core.getStartServices()).pipe( + map(([coreStart]) => { + if (coreStart.application.capabilities.apm.show) { + return [ + // APM navigation + { + label: 'APM', + sortKey: 200, + entries: [ + { label: servicesTitle, app: 'apm', path: '/services' }, + { label: tracesTitle, app: 'apm', path: '/traces' }, + { label: serviceMapTitle, app: 'apm', path: '/service-map' }, + ], + }, + + // UX navigation + { + label: 'User Experience', + sortKey: 201, + entries: [ + { + label: i18n.translate('xpack.apm.ux.overview.heading', { + defaultMessage: 'Overview', + }), + app: 'ux', + path: '/', + matchFullPath: true, + ignoreTrailingSlash: true, + }, + ], + }, + ]; + } + + return []; + }) + ) ); const getApmDataHelper = async () => { @@ -150,26 +188,6 @@ export class ApmPlugin implements Plugin { }, }); - plugins.observability.navigation.registerSections( - of([ - { - label: 'User Experience', - sortKey: 201, - entries: [ - { - label: i18n.translate('xpack.apm.ux.overview.heading', { - defaultMessage: 'Overview', - }), - app: 'ux', - path: '/', - matchFullPath: true, - ignoreTrailingSlash: true, - }, - ], - }, - ]) - ); - core.application.register({ id: 'apm', title: 'APM', @@ -178,29 +196,10 @@ export class ApmPlugin implements Plugin { appRoute: '/app/apm', icon: 'plugins/apm/public/icon.svg', category: DEFAULT_APP_CATEGORIES.observability, - // !! Need to be kept in sync with the routes in x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx deepLinks: [ - { - id: 'services', - title: i18n.translate('xpack.apm.breadcrumb.servicesTitle', { - defaultMessage: 'Services', - }), - path: '/services', - }, - { - id: 'traces', - title: i18n.translate('xpack.apm.breadcrumb.tracesTitle', { - defaultMessage: 'Traces', - }), - path: '/traces', - }, - { - id: 'service-map', - title: i18n.translate('xpack.apm.breadcrumb.serviceMapTitle', { - defaultMessage: 'Service Map', - }), - path: '/service-map', - }, + { id: 'services', title: servicesTitle, path: '/services' }, + { id: 'traces', title: tracesTitle, path: '/traces' }, + { id: 'service-map', title: serviceMapTitle, path: '/service-map' }, ], async mount(appMountParameters: AppMountParameters) { diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/flash_messages_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/flash_messages_logic.mock.ts similarity index 89% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/flash_messages_logic.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/flash_messages_logic.mock.ts index 6c31927cd75b09..36a10fd234bfe0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/flash_messages_logic.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/flash_messages_logic.mock.ts @@ -29,8 +29,8 @@ export const mockFlashMessageHelpers = { flashErrorToast: jest.fn(), }; -jest.mock('../shared/flash_messages', () => ({ - ...(jest.requireActual('../shared/flash_messages') as object), +jest.mock('../../shared/flash_messages', () => ({ + ...(jest.requireActual('../../shared/flash_messages') as object), ...mockFlashMessageHelpers, FlashMessagesLogic: { values: mockFlashMessagesValues, diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/hooks.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/hooks.mock.ts new file mode 100644 index 00000000000000..ce21fd08f180ad --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/hooks.mock.ts @@ -0,0 +1,65 @@ +/* + * 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. + */ + +/** + * Combine all shared mock values/actions into a single obj + * + * NOTE: These variable names MUST start with 'mock*' in order for + * Jest to accept its use within a jest.mock() + */ +import { mockFlashMessagesValues, mockFlashMessagesActions } from './flash_messages_logic.mock'; +import { mockHttpValues } from './http_logic.mock'; +import { mockKibanaValues } from './kibana_logic.mock'; +import { mockLicensingValues } from './licensing_logic.mock'; +import { mockTelemetryActions } from './telemetry_logic.mock'; + +export const mockAllValues = { + ...mockKibanaValues, + ...mockLicensingValues, + ...mockHttpValues, + ...mockFlashMessagesValues, +}; +export const mockAllActions = { + ...mockTelemetryActions, + ...mockFlashMessagesActions, +}; + +/** + * Import this file directly to mock useValues with a set of default values for all shared logic files. + * Example usage: + * + * import '../../../__mocks__/kea_logic'; // Must come before kea's import, adjust relative path as needed + */ +jest.mock('kea', () => ({ + ...(jest.requireActual('kea') as object), + useValues: jest.fn(() => ({ ...mockAllValues })), + useActions: jest.fn(() => ({ ...mockAllActions })), +})); + +/** + * React component helpers + * + * Call this function to override a specific set of Kea values while retaining all other defaults + * + * Example usage: + * + * import { setMockValues } from '../../../__mocks__/kea_logic'; + * import { SomeComponent } from './'; + * + * it('some test', () => { + * setMockValues({ someValue: 'hello' }); + * shallow(); + * }); + */ +import { useValues, useActions } from 'kea'; + +export const setMockValues = (values: object) => { + (useValues as jest.Mock).mockImplementation(() => ({ ...mockAllValues, ...values })); +}; +export const setMockActions = (actions: object) => { + (useActions as jest.Mock).mockImplementation(() => ({ ...mockAllActions, ...actions })); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/http_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/http_logic.mock.ts similarity index 92% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/http_logic.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/http_logic.mock.ts index 5399646a7b4148..e60f5a1a8ba120 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/http_logic.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/http_logic.mock.ts @@ -13,6 +13,6 @@ export const mockHttpValues = { readOnlyMode: false, }; -jest.mock('../shared/http', () => ({ +jest.mock('../../shared/http', () => ({ HttpLogic: { values: mockHttpValues }, })); diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/index.ts similarity index 53% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts rename to x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/index.ts index 4e3a344b52e465..81901e6d0e1036 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/index.ts @@ -5,7 +5,6 @@ * 2.0. */ -export { mockHistory, mockLocation } from './react_router_history.mock'; export { mockKibanaValues } from './kibana_logic.mock'; export { mockLicensingValues } from './licensing_logic.mock'; export { mockHttpValues } from './http_logic.mock'; @@ -15,18 +14,6 @@ export { mockFlashMessagesActions, mockFlashMessageHelpers, } from './flash_messages_logic.mock'; -export { - mockAllValues, - mockAllActions, - setMockValues, - setMockActions, - LogicMounter, -} from './kea.mock'; - -export { mountAsync } from './mount_async.mock'; -export { mountWithIntl } from './mount_with_i18n.mock'; -export { shallowWithIntl } from './shallow_with_i18n.mock'; -export { rerender } from './enzyme_rerender.mock'; -// Note: shallow_useeffect must be imported directly as a file +export { mockAllValues, mockAllActions, setMockValues, setMockActions } from './hooks.mock'; -export { expectedAsyncError } from './expected_async_error'; +export { LogicMounter } from './logic_mounter.test_helper'; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/kibana_logic.mock.ts similarity index 79% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/kibana_logic.mock.ts index 1ebd61df388c5a..ebb6f8c4fe5aad 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/kibana_logic.mock.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { mockHistory } from './react_router_history.mock'; +import { chartPluginMock } from '../../../../../../../src/plugins/charts/public/mocks'; -import { chartPluginMock } from '../../../../../../src/plugins/charts/public/mocks'; +import { mockHistory } from '../react_router/state.mock'; export const mockKibanaValues = { config: { host: 'http://localhost:3002' }, @@ -24,6 +24,6 @@ export const mockKibanaValues = { renderHeaderActions: jest.fn(), }; -jest.mock('../shared/kibana', () => ({ +jest.mock('../../shared/kibana', () => ({ KibanaLogic: { values: mockKibanaValues }, })); diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/licensing_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/licensing_logic.mock.ts similarity index 79% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/licensing_logic.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/licensing_logic.mock.ts index d39ba56cdc1c1b..2cea6061b63ab8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/licensing_logic.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/licensing_logic.mock.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { licensingMock } from '../../../../licensing/public/mocks'; +import { licensingMock } from '../../../../../licensing/public/mocks'; export const mockLicensingValues = { license: licensingMock.createLicense(), @@ -13,6 +13,6 @@ export const mockLicensingValues = { hasGoldLicense: false, }; -jest.mock('../shared/licensing', () => ({ +jest.mock('../../shared/licensing', () => ({ LicensingLogic: { values: mockLicensingValues }, })); diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/logic_mounter.test_helper.ts similarity index 62% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/logic_mounter.test_helper.ts index 4ebb9edd20c0e2..08867fe944d15f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/logic_mounter.test_helper.ts @@ -6,67 +6,6 @@ */ /** - * Combine all shared mock values/actions into a single obj - * - * NOTE: These variable names MUST start with 'mock*' in order for - * Jest to accept its use within a jest.mock() - */ -import { mockFlashMessagesValues, mockFlashMessagesActions } from './flash_messages_logic.mock'; -import { mockHttpValues } from './http_logic.mock'; -import { mockKibanaValues } from './kibana_logic.mock'; -import { mockLicensingValues } from './licensing_logic.mock'; -import { mockTelemetryActions } from './telemetry_logic.mock'; - -export const mockAllValues = { - ...mockKibanaValues, - ...mockLicensingValues, - ...mockHttpValues, - ...mockFlashMessagesValues, -}; -export const mockAllActions = { - ...mockTelemetryActions, - ...mockFlashMessagesActions, -}; - -/** - * Import this file directly to mock useValues with a set of default values for all shared logic files. - * Example usage: - * - * import '../../../__mocks__/kea'; // Must come before kea's import, adjust relative path as needed - */ -jest.mock('kea', () => ({ - ...(jest.requireActual('kea') as object), - useValues: jest.fn(() => ({ ...mockAllValues })), - useActions: jest.fn(() => ({ ...mockAllActions })), -})); - -/** - * React component helpers - * - * Call this function to override a specific set of Kea values while retaining all other defaults - * - * Example usage: - * - * import { setMockValues } from '../../../__mocks__/kea.mock'; - * import { SomeComponent } from './'; - * - * it('some test', () => { - * setMockValues({ someValue: 'hello' }); - * shallow(); - * }); - */ -import { useValues, useActions } from 'kea'; - -export const setMockValues = (values: object) => { - (useValues as jest.Mock).mockImplementation(() => ({ ...mockAllValues, ...values })); -}; -export const setMockActions = (actions: object) => { - (useActions as jest.Mock).mockImplementation(() => ({ ...mockAllActions, ...actions })); -}; - -/** - * Kea logic helpers - * * Call this function to mount a logic file and optionally override default values. * Automatically DRYs out a lot of cruft for us, such as resetting context, creating the * nested defaults path obj (see https://kea.js.org/docs/api/context#resetcontext), and @@ -74,7 +13,7 @@ export const setMockActions = (actions: object) => { * * Example usage: * - * import { LogicMounter } from '../../../__mocks__/kea.mock'; + * import { LogicMounter } from '../../../__mocks__/kea_logic'; * import { SomeLogic } from './'; * * const { mount, unmount } = new LogicMounter(SomeLogic); diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/telemetry_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/telemetry_logic.mock.ts similarity index 82% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/telemetry_logic.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/telemetry_logic.mock.ts index 01b2e7cf103fb4..fbc1537e733e7c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/telemetry_logic.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea_logic/telemetry_logic.mock.ts @@ -12,7 +12,7 @@ export const mockTelemetryActions = { sendWorkplaceSearchTelemetry: jest.fn(), }; -jest.mock('../shared/telemetry', () => ({ - ...(jest.requireActual('../shared/telemetry') as object), +jest.mock('../../shared/telemetry', () => ({ + ...(jest.requireActual('../../shared/telemetry') as object), TelemetryLogic: { actions: mockTelemetryActions }, })); diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router/hooks.mock.ts similarity index 53% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router/hooks.mock.ts index 8f0c63d46c8e7c..5e867da7607fea 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router/hooks.mock.ts @@ -5,34 +5,21 @@ * 2.0. */ -/** - * NOTE: These variable names MUST start with 'mock*' in order for - * Jest to accept its use within a jest.mock() - */ -export const mockHistory = { - createHref: jest.fn(({ pathname }) => `/app/enterprise_search${pathname}`), - push: jest.fn(), - location: { - pathname: '/current-path', - }, - listen: jest.fn(() => jest.fn()), -} as any; -export const mockLocation = { - key: 'someKey', - pathname: '/current-path', - search: '?query=something', - hash: '#hash', - state: {}, -}; +import { mockHistory, mockLocation } from './state.mock'; + +export const mockUseHistory = jest.fn(() => mockHistory); +export const mockUseLocation = jest.fn(() => mockLocation); +export const mockUseParams = jest.fn(() => ({})); +export const mockUseRouteMatch = jest.fn(() => true); jest.mock('react-router-dom', () => { const originalModule = jest.requireActual('react-router-dom'); return { ...originalModule, - useHistory: jest.fn(() => mockHistory), - useLocation: jest.fn(() => mockLocation), - useParams: jest.fn(() => ({})), - useRouteMatch: jest.fn(() => null), + useHistory: mockUseHistory, + useLocation: mockUseLocation, + useParams: mockUseParams, + useRouteMatch: mockUseRouteMatch, // Note: RR's generatePath() opinionatedly encodeURI()s paths (although this doesn't actually // show up/affect the final browser URL). Since we already have a generateEncodedPath helper & // RR is removing this behavior in history 5.0+, I'm mocking tests to remove the extra encoding @@ -40,7 +27,3 @@ jest.mock('react-router-dom', () => { generatePath: jest.fn((path, params) => decodeURI(originalModule.generatePath(path, params))), }; }); - -/** - * For example usage, @see public/applications/shared/react_router_helpers/eui_link.test.tsx - */ diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router/index.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router/index.ts new file mode 100644 index 00000000000000..0bf83135407b3b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router/index.ts @@ -0,0 +1,13 @@ +/* + * 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. + */ + +// State and hooks are stored in separate mock files for when a file needs to +// import a basic history mock without automatically jest.mock()ing all of React Router +export * from './state.mock'; +export * from './hooks.mock'; + +// For example usage, @see public/applications/shared/react_router_helpers/eui_link.test.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router/state.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router/state.mock.ts new file mode 100644 index 00000000000000..0ce8673530b008 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router/state.mock.ts @@ -0,0 +1,28 @@ +/* + * 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. + */ + +/** + * NOTE: These variable names MUST start with 'mock*' in order for + * Jest to accept its use within a jest.mock() + */ + +export const mockHistory = { + createHref: jest.fn(({ pathname }) => `/app/enterprise_search${pathname}`), + push: jest.fn(), + location: { + pathname: '/current-path', + }, + listen: jest.fn(() => jest.fn()), +} as any; + +export const mockLocation = { + key: 'someKey', + pathname: '/current-path', + search: '?query=something', + hash: '#hash', + state: {}, +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts index f6497e5f5266b4..7b08e82a4cf209 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts @@ -6,7 +6,7 @@ */ import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__'; -import { LogicMounter } from '../__mocks__'; +import { LogicMounter } from '../__mocks__/kea_logic'; import { AppLogic } from './app_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.test.tsx index 291df04746418d..9832915f19e9ed 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.test.tsx @@ -6,16 +6,16 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import '../../../__mocks__/react_router_history.mock'; -import { mockKibanaValues, setMockValues, setMockActions, rerender } from '../../../__mocks__'; +import { mockKibanaValues, setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; +import { mockUseParams } from '../../../__mocks__/react_router'; import React from 'react'; -import { useParams } from 'react-router-dom'; import { shallow } from 'enzyme'; import { FlashMessages } from '../../../shared/flash_messages'; import { Loading } from '../../../shared/loading'; +import { rerender } from '../../../test_helpers'; import { LogRetentionCallout } from '../log_retention'; import { AnalyticsLayout } from './analytics_layout'; @@ -63,7 +63,7 @@ describe('AnalyticsLayout', () => { describe('data loading', () => { it('loads query data for query details pages', () => { - (useParams as jest.Mock).mockReturnValueOnce({ query: 'test' }); + mockUseParams.mockReturnValueOnce({ query: 'test' }); shallow(); expect(actions.loadQueryData).toHaveBeenCalledWith('test'); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.test.ts index 3359143ad36720..921a0892bb8905 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.test.ts @@ -10,7 +10,7 @@ import { mockKibanaValues, mockHttpValues, mockFlashMessageHelpers, -} from '../../../__mocks__'; +} from '../../../__mocks__/kea_logic'; jest.mock('../engine', () => ({ EngineLogic: { values: { engineName: 'test-engine' } }, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.test.tsx index 51238d62bdac77..8a5d2cbf89c4af 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { mockKibanaValues } from '../../../../__mocks__'; +import { mockKibanaValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.test.tsx index 952c4c2517a0ee..5269ea91100659 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, mockKibanaValues } from '../../../../__mocks__'; +import { setMockValues, mockKibanaValues } from '../../../../__mocks__/kea_logic'; import React, { ReactElement } from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.test.tsx index 89fa5b4cc4b736..de04a21d48a23e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.test.tsx @@ -5,7 +5,8 @@ * 2.0. */ -import { mockKibanaValues } from '../../../../__mocks__'; +import { mockKibanaValues } from '../../../../__mocks__/kea_logic'; +import '../../../../__mocks__/react_router'; import '../../../__mocks__/engine_logic.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.test.tsx index 624cc57e1eb221..e25e4d8c16bb24 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.test.tsx @@ -5,13 +5,16 @@ * 2.0. */ -import { mountWithIntl } from '../../../../../__mocks__'; +import '../../../../../__mocks__/kea_logic'; +import '../../../../../__mocks__/react_router'; import '../../../../__mocks__/engine_logic.mock'; import React from 'react'; import { EuiBasicTable, EuiBadge, EuiEmptyPrompt } from '@elastic/eui'; +import { mountWithIntl } from '../../../../../test_helpers'; + import { runActionColumnTests } from './test_helpers/shared_columns_tests'; import { AnalyticsTable } from './'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.test.tsx index cc8f13299c57f6..00cb12060822e4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.test.tsx @@ -5,13 +5,16 @@ * 2.0. */ -import { mountWithIntl } from '../../../../../__mocks__'; +import '../../../../../__mocks__/kea_logic'; +import '../../../../../__mocks__/react_router'; import '../../../../__mocks__/engine_logic.mock'; import React from 'react'; import { EuiBasicTable, EuiLink, EuiBadge, EuiEmptyPrompt } from '@elastic/eui'; +import { mountWithIntl } from '../../../../../test_helpers'; + import { QueryClicksTable } from './'; describe('QueryClicksTable', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.test.tsx index 60213631830980..6ec89751a62e9d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.test.tsx @@ -5,13 +5,16 @@ * 2.0. */ -import { mountWithIntl } from '../../../../../__mocks__'; +import '../../../../../__mocks__/kea_logic'; +import '../../../../../__mocks__/react_router'; import '../../../../__mocks__/engine_logic.mock'; import React from 'react'; import { EuiBasicTable, EuiBadge, EuiEmptyPrompt } from '@elastic/eui'; +import { mountWithIntl } from '../../../../../test_helpers'; + import { runActionColumnTests } from './test_helpers/shared_columns_tests'; import { RecentQueriesTable } from './'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/test_helpers/shared_columns_tests.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/test_helpers/shared_columns_tests.tsx index 95af7b52487d4e..cb3d340debd048 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/test_helpers/shared_columns_tests.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/test_helpers/shared_columns_tests.tsx @@ -9,7 +9,7 @@ import { mockHttpValues, mockKibanaValues, mockFlashMessageHelpers, -} from '../../../../../../__mocks__'; +} from '../../../../../../__mocks__/kea_logic'; import '../../../../../__mocks__/engine_logic.mock'; import { ReactWrapper } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.test.tsx index 688d5dec1a9587..8496be6223764e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import '../../../__mocks__/engine_logic.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.test.tsx index 978f11ddfd5cd5..a942918fa9c623 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.test.tsx @@ -5,11 +5,10 @@ * 2.0. */ -import '../../../../__mocks__/react_router_history.mock'; -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; +import { mockUseParams } from '../../../../__mocks__/react_router'; import React from 'react'; -import { useParams } from 'react-router-dom'; import { shallow } from 'enzyme'; @@ -24,7 +23,7 @@ describe('QueryDetail', () => { const mockBreadcrumbs = ['Engines', 'some-engine', 'Analytics']; beforeEach(() => { - (useParams as jest.Mock).mockReturnValue({ query: 'some-query' }); + mockUseParams.mockReturnValue({ query: 'some-query' }); setMockValues({ totalQueriesForQuery: 100, @@ -50,7 +49,7 @@ describe('QueryDetail', () => { }); it('renders empty "" search titles correctly', () => { - (useParams as jest.Mock).mockReturnValue({ query: '""' }); + mockUseParams.mockReturnValue({ query: '""' }); const wrapper = shallow(); expect(wrapper.find(AnalyticsLayout).prop('title')).toEqual('""'); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.test.tsx index 21d515a7b97950..20a25db3a7adf5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.test.tsx index 46b2b379584350..98362e42c5536f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.test.tsx index 83212160d13508..dfbda1c68ca84b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.test.tsx index dfc5b9c93ab64f..60e33660f87d72 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.test.tsx index fb967ca06b387a..b4c9f0fb40f718 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx index 6bebeee80465c8..3ff22479f4013d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import { mockApiLog } from '../__mocks__/api_log.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx index 2b7ca7510e8e14..e0d7c30bd01417 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter } from '../../../../__mocks__'; +import { LogicMounter } from '../../../../__mocks__/kea_logic'; import { mockApiLog } from '../__mocks__/api_log.mock'; import { ApiLogLogic } from './'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.test.tsx index cb29d92030ad7f..c2a11ec06fa6a4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions, rerender } from '../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import '../../../__mocks__/shallow_useeffect.mock'; import '../../__mocks__/engine_logic.mock'; @@ -16,6 +16,7 @@ import { shallow } from 'enzyme'; import { EuiPageHeader } from '@elastic/eui'; import { Loading } from '../../../shared/loading'; +import { rerender } from '../../../test_helpers'; import { LogRetentionCallout, LogRetentionTooltip } from '../log_retention'; import { ApiLogsTable, NewApiEventsPrompt } from './components'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts index 2eda4c6323fa5c..5af5dca3e97dc3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__'; +import { + LogicMounter, + mockHttpValues, + mockFlashMessageHelpers, +} from '../../../__mocks__/kea_logic'; import { mockApiLog } from './__mocks__/api_log.mock'; import '../../__mocks__/engine_logic.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx index 780c198a9fac52..2a00cc6eb42bb3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions, mountWithIntl } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; // NOTE: We're mocking FormattedRelative here because it (currently) has // console warn issues, and it allows us to skip mocking dates @@ -21,6 +21,7 @@ import { shallow } from 'enzyme'; import { EuiBasicTable, EuiBadge, EuiHealth, EuiButtonEmpty, EuiEmptyPrompt } from '@elastic/eui'; import { DEFAULT_META } from '../../../../shared/constants'; +import { mountWithIntl } from '../../../../test_helpers'; import { ApiLogsTable } from './'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/new_api_events_prompt.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/new_api_events_prompt.test.tsx index 91d1962cd91db8..5fd1d12f248429 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/new_api_events_prompt.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/new_api_events_prompt.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_landing.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_landing.test.tsx index 132579bad8bdc0..045fd9ee7be1b4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_landing.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_landing.test.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { setMockValues } from '../../../__mocks__'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import { mockEngineValues } from '../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx index eb30ae867b4b6d..cc3fa21f733097 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { rerender, setMockActions, setMockValues } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import '../../../__mocks__/shallow_useeffect.mock'; import React from 'react'; @@ -15,6 +15,7 @@ import { shallow, ShallowWrapper } from 'enzyme'; import { EuiCode } from '@elastic/eui'; import { Loading } from '../../../shared/loading'; +import { rerender } from '../../../test_helpers'; import { CrawlerOverview } from './crawler_overview'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview_logic.test.ts index 766f5dcfa02dc3..f23322337766a1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__'; +import { + LogicMounter, + mockHttpValues, + mockFlashMessageHelpers, +} from '../../../__mocks__/kea_logic'; import '../../__mocks__/engine_logic.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.test.tsx index 351f5474478033..c11c6563330104 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.test.tsx @@ -4,8 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { setMockValues } from '../../../__mocks__'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import { mockEngineValues } from '../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx index 3785873461f163..286658c011002d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.test.tsx index 595bc1bcbb828b..1ca6c0ce828557 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.test.tsx index 23e85b92bb8b48..d3312b5a1e3694 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx index 7247deb09f12b9..d39ffb2bea2062 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions, rerender } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; @@ -13,6 +13,8 @@ import { shallow } from 'enzyme'; import { EuiRadio, EuiCheckbox } from '@elastic/eui'; +import { rerender } from '../../../../../test_helpers'; + import { FormKeyEngineAccess, EngineSelection } from './key_engine_access'; describe('FormKeyEngineAccess', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.test.tsx index d54d0c89c90cb9..a206cdef4a7377 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.test.tsx index cf45576d691cf3..6f52a27dd628d7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.test.tsx index 5de2c7fda53ca2..9cd518be2aaa5f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.test.tsx index 8ee7f810c1fa5c..019a6c7043fb0b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.test.tsx index 9932b8ca227b0d..b86c1c592c4cd7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.test.tsx index 274bda56a2fc12..13dd77da40931e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts index bf84b03e7603ee..7192488e497465 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.test.tsx index ad4ba100145d98..937acfd84ce83d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.test.tsx @@ -5,12 +5,11 @@ * 2.0. */ -import '../../../../__mocks__/react_router_history.mock'; import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues, rerender } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; +import { mockUseParams } from '../../../../__mocks__/react_router'; import React from 'react'; -import { useParams } from 'react-router-dom'; import { shallow, ShallowWrapper } from 'enzyme'; @@ -18,6 +17,7 @@ import { EuiPageHeader } from '@elastic/eui'; import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome'; import { Loading } from '../../../../shared/loading'; +import { rerender } from '../../../../test_helpers'; jest.mock('./curation_logic', () => ({ CurationLogic: jest.fn() })); import { CurationLogic } from './curation_logic'; @@ -71,18 +71,18 @@ describe('Curation', () => { }); it('initializes CurationLogic with a curationId prop from URL param', () => { - (useParams as jest.Mock).mockReturnValueOnce({ curationId: 'hello-world' }); + mockUseParams.mockReturnValueOnce({ curationId: 'hello-world' }); shallow(); expect(CurationLogic).toHaveBeenCalledWith({ curationId: 'hello-world' }); }); it('calls loadCuration on page load & whenever the curationId URL param changes', () => { - (useParams as jest.Mock).mockReturnValueOnce({ curationId: 'cur-123456789' }); + mockUseParams.mockReturnValueOnce({ curationId: 'cur-123456789' }); const wrapper = shallow(); expect(actions.loadCuration).toHaveBeenCalledTimes(1); - (useParams as jest.Mock).mockReturnValueOnce({ curationId: 'cur-987654321' }); + mockUseParams.mockReturnValueOnce({ curationId: 'cur-987654321' }); rerender(wrapper); expect(actions.loadCuration).toHaveBeenCalledTimes(2); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation_logic.test.ts index 17f7cd7cd154e6..db387f581b92e1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation_logic.test.ts @@ -10,7 +10,7 @@ import { mockHttpValues, mockKibanaValues, mockFlashMessageHelpers, -} from '../../../../__mocks__'; +} from '../../../../__mocks__/kea_logic'; import '../../../__mocks__/engine_logic.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/hidden_documents.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/hidden_documents.test.tsx index 7ffa45c2853206..c2377d0109494e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/hidden_documents.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/hidden_documents.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/organic_documents.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/organic_documents.test.tsx index 2a83ecfcada444..0624d0063e57d6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/organic_documents.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/organic_documents.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/promoted_documents.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/promoted_documents.test.tsx index 7240a443b76e90..e0c6de973666c3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/promoted_documents.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/promoted_documents.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/queries/active_query_select.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/queries/active_query_select.test.tsx index 65e8dbc96b6365..f27c7ef959b50e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/queries/active_query_select.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/queries/active_query_select.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/queries/manage_queries_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/queries/manage_queries_modal.test.tsx index 7fe992cdd96e2b..1ff34c5875a0c6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/queries/manage_queries_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/queries/manage_queries_modal.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_button.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_button.test.tsx index 19fc7e1784d3d5..53cefdd00c670c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_button.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_button.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../../__mocks__'; +import { setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_flyout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_flyout.test.tsx index a0f178aca32b29..71469e4e3f8cba 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_flyout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_flyout.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_logic.test.ts index e7007cdc093cb4..f1013fa4a6dfb5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/add_result_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter } from '../../../../../__mocks__'; +import { LogicMounter } from '../../../../../__mocks__/kea_logic'; import '../../../../__mocks__/engine_logic.mock'; import { AddResultLogic } from './'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.test.tsx index 460c0f4dfa44c7..67a26f2ecd4b6d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../../__mocks__'; +import { setMockValues } from '../../../../../__mocks__/kea_logic'; import React from 'react'; import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_logic.test.ts index c1031fc20bc15d..f00f744f730ab4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_logic.test.ts @@ -10,7 +10,7 @@ import { mockHttpValues, mockKibanaValues, mockFlashMessageHelpers, -} from '../../../__mocks__'; +} from '../../../__mocks__/kea_logic'; import '../../__mocks__/engine_logic.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.test.tsx index 258d0ec6231fcd..ad306dfc730802 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../__mocks__'; +import { setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx index 1be21c97c623bf..bcc402d6eea273 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx @@ -5,12 +5,7 @@ * 2.0. */ -import { - mountWithIntl, - mockKibanaValues, - setMockActions, - setMockValues, -} from '../../../../__mocks__'; +import { mockKibanaValues, setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import '../../../__mocks__/engine_logic.mock'; import React from 'react'; @@ -20,6 +15,7 @@ import { shallow, ReactWrapper } from 'enzyme'; import { EuiPageHeader, EuiBasicTable } from '@elastic/eui'; import { Loading } from '../../../../shared/loading'; +import { mountWithIntl } from '../../../../test_helpers'; import { EmptyState } from '../components'; import { Curations, CurationsTable } from './curations'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.test.tsx index 34afa9d1e39edb..b0cf40713142ad 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../__mocks__/enterprise_search_url.mock'; -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx index 8b5b36094fbc66..863e87a28f40e3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions, rerender } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; @@ -13,6 +13,8 @@ import { shallow } from 'enzyme'; import { EuiTextArea, EuiButtonEmpty, EuiButton } from '@elastic/eui'; +import { rerender } from '../../../../test_helpers'; + import { Errors } from '../creation_response_components'; import { PasteJsonText, FlyoutHeader, FlyoutBody, FlyoutFooter } from './paste_json_text'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.test.tsx index 739580d039a36e..1087e3d9275597 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx index 7dc8952a18688f..9b8820434fad8f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions, rerender } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; @@ -13,6 +13,8 @@ import { shallow } from 'enzyme'; import { EuiFilePicker, EuiButtonEmpty, EuiButton } from '@elastic/eui'; +import { rerender } from '../../../../test_helpers'; + import { Errors } from '../creation_response_components'; import { UploadJsonFile, FlyoutHeader, FlyoutBody, FlyoutFooter } from './upload_json_file'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.test.tsx index f03989aeaf5a3d..3a3e7fd66d314a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.test.tsx index f53f94322879c5..39608c6e8f81df 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.test.tsx index 7eb9f3f46036d9..7843b8bbf907b1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.test.tsx index 7cbcc6b17e047d..f293a0050eac9f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../__mocks__/kea_logic'; import '../../__mocks__/engine_logic.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.test.tsx index 66995b8d20dfe3..3dc5d445930ba3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts index 2c6cadf9a8ece5..a75cb785367835 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter, mockHttpValues } from '../../../__mocks__'; +import { LogicMounter, mockHttpValues } from '../../../__mocks__/kea_logic'; import dedent from 'dedent'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/document_creation_button.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/document_creation_button.test.tsx index a6ccdc180b415d..e9b74a56d0e503 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/document_creation_button.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/document_creation_button.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx index c4563b43571345..4aade8e61b0851 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx @@ -5,13 +5,12 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; +import { mockUseParams } from '../../../__mocks__/react_router'; import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock'; -import '../../../__mocks__/react_router_history.mock'; import '../../__mocks__/engine_logic.mock'; import React from 'react'; -import { useParams } from 'react-router-dom'; import { shallow } from 'enzyme'; @@ -39,7 +38,7 @@ describe('DocumentDetail', () => { setMockValues(values); setMockActions(actions); - (useParams as jest.Mock).mockImplementationOnce(() => ({ + mockUseParams.mockImplementationOnce(() => ({ documentId: '1', })); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts index 565c3069788c09..a258dcd970c745 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts @@ -10,7 +10,7 @@ import { mockHttpValues, mockKibanaValues, mockFlashMessageHelpers, -} from '../../../__mocks__'; +} from '../../../__mocks__/kea_logic'; import { mockEngineValues } from '../../__mocks__'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx index 88f5b6a1c49e65..143ad3f55ff2fb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import '../../__mocks__/engine_logic.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents_logic.test.ts index c1d30a3cdd401c..29b2c835f8260f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter } from '../../../__mocks__/kea.mock'; +import { LogicMounter } from '../../../__mocks__/kea_logic'; import { DocumentsLogic } from './documents_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.test.tsx index 332c5b822eb6d8..536698ffe28f32 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx index e5f2978e5ba925..a4d1a92ee45a4f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../__mocks__/enterprise_search_url.mock'; -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.test.tsx index ea111402309b40..44a6da51ec8d68 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import { setMockSearchContextState } from './__mocks__/hooks.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts index 836265a037e169..2b60193d4f7d3d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter, mockHttpValues } from '../../../__mocks__'; +import { LogicMounter, mockHttpValues } from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx index d913e3921bf1b6..c2b0a6a50fd068 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, rerender } from '../../../__mocks__'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import { mockEngineValues } from '../../__mocks__'; import React from 'react'; @@ -14,6 +14,8 @@ import { shallow } from 'enzyme'; import { EuiBadge, EuiIcon } from '@elastic/eui'; +import { rerender } from '../../../test_helpers'; + import { EngineNav } from './engine_nav'; describe('EngineNav', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx index 3eab209d706fad..b74c31adca4386 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx @@ -5,13 +5,17 @@ * 2.0. */ -import '../../../__mocks__/react_router_history.mock'; -import { mockFlashMessageHelpers, setMockValues, setMockActions } from '../../../__mocks__'; +import { + mockFlashMessageHelpers, + setMockValues, + setMockActions, +} from '../../../__mocks__/kea_logic'; +import { mockUseParams } from '../../../__mocks__/react_router'; import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock'; import { mockEngineValues } from '../../__mocks__'; import React from 'react'; -import { Switch, Redirect, useParams } from 'react-router-dom'; +import { Switch, Redirect } from 'react-router-dom'; import { shallow } from 'enzyme'; @@ -43,7 +47,7 @@ describe('EngineRouter', () => { beforeEach(() => { setMockValues(values); setMockActions(actions); - (useParams as jest.Mock).mockReturnValue({ engineName: 'some-engine' }); + mockUseParams.mockReturnValue({ engineName: 'some-engine' }); }); describe('useEffect', () => { @@ -87,7 +91,7 @@ describe('EngineRouter', () => { // any route views as they would be rendering with the wrong data. it('renders a loading component if the engine stored in state is stale', () => { setMockValues({ ...values, engineName: 'some-engine' }); - (useParams as jest.Mock).mockReturnValue({ engineName: 'some-new-engine' }); + mockUseParams.mockReturnValue({ engineName: 'some-new-engine' }); const wrapper = shallow(); expect(wrapper.find(Loading)).toHaveLength(1); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx index 9d1bbafc826622..b91e33d1c8a927 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts index 6d5c4480e45f65..1e87b3ef21f03f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.test.ts @@ -10,7 +10,7 @@ import { mockHttpValues, mockKibanaValues, mockFlashMessageHelpers, -} from '../../../__mocks__'; +} from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.test.tsx index 6f3ec806a438d8..1281d8f23a7eb7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../__mocks__'; +import { setMockActions } from '../../../../__mocks__/kea_logic'; import '../../../../__mocks__/shallow_useeffect.mock'; import '../../../__mocks__/engine_logic.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.test.tsx index 74ce770205ffe7..b20b71487307db 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import '../../../__mocks__/engine_logic.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.test.tsx index 7fcda61073c5b5..28a63c5d368429 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx index d2d69de72c1100..a3b2f4cfd8b9f5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx @@ -6,7 +6,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_logic.test.ts index b790edef43cc4c..c9c1defd46032b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__'; +import { + LogicMounter, + mockHttpValues, + mockFlashMessageHelpers, +} from '../../../__mocks__/kea_logic'; jest.mock('../engine', () => ({ EngineLogic: { values: { engineName: 'some-engine' } }, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx index 222041c9f85a37..159a986096ae2a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx @@ -5,8 +5,7 @@ * 2.0. */ -import '../../../../__mocks__/kea.mock'; -import { setMockValues, mockTelemetryActions } from '../../../../__mocks__'; +import { setMockValues, mockTelemetryActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.test.tsx index 8cb26713cb8408..9b245a468b0838 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../__mocks__/enterprise_search_url.mock'; -import { mockTelemetryActions } from '../../../../__mocks__'; +import { mockTelemetryActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/engine_link_helpers.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/engine_link_helpers.test.tsx index 5d91c724068e75..1ddf6e40ce1ff8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/engine_link_helpers.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/engine_link_helpers.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { mockKibanaValues, mockTelemetryActions } from '../../../../../__mocks__'; +import { mockKibanaValues, mockTelemetryActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/engines_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/engines_table.test.tsx index 8d3b4b2a5e6cac..b9369d019a2f8a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/engines_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/engines_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { mountWithIntl, setMockValues } from '../../../../../__mocks__'; +import { setMockValues } from '../../../../../__mocks__/kea_logic'; import '../../../../../__mocks__/enterprise_search_url.mock'; import './__mocks__/engines_logic.mock'; @@ -15,6 +15,8 @@ import { shallow } from 'enzyme'; import { EuiBasicTable } from '@elastic/eui'; +import { mountWithIntl } from '../../../../../test_helpers'; + import { EngineDetails } from '../../../engine/types'; import { EnginesTable } from './engines_table'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table.test.tsx index 430539c10bbf37..fb258e1e3be8c6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { mountWithIntl, setMockValues } from '../../../../../__mocks__'; +import { setMockValues } from '../../../../../__mocks__/kea_logic'; import '../../../../../__mocks__/enterprise_search_url.mock'; import './__mocks__/engines_logic.mock'; @@ -15,6 +15,8 @@ import { shallow } from 'enzyme'; import { EuiBasicTable } from '@elastic/eui'; +import { mountWithIntl } from '../../../../../test_helpers'; + import { EngineDetails } from '../../../engine/types'; import { MetaEnginesTable } from './meta_engines_table'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table_expanded_row.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table_expanded_row.test.tsx index dcaa1a2b7c2461..26c8c0fddcd11f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table_expanded_row.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table_expanded_row.test.tsx @@ -5,14 +5,14 @@ * 2.0. */ -import { mountWithIntl } from '../../../../../__mocks__'; - import React from 'react'; import { shallow } from 'enzyme'; import { EuiBasicTable, EuiHealth } from '@elastic/eui'; +import { mountWithIntl } from '../../../../../test_helpers'; + import { EngineDetails } from '../../../engine/types'; import { MetaEnginesTableExpandedRow } from './meta_engines_table_expanded_row'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table_logic.test.ts index de1902c7cf748f..3c0b9c4dc33f66 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/meta_engines_table_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter } from '../../../../../__mocks__'; +import { LogicMounter } from '../../../../../__mocks__/kea_logic'; import { mockRecursivelyFetchEngines } from '../../../../__mocks__/recursively_fetch_engines.mock'; import { EngineDetails } from '../../../engine/types'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/test_helpers/shared_columns.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/test_helpers/shared_columns.tsx index 97e2057cea2d96..b46dfa7e19dd92 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/test_helpers/shared_columns.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/tables/test_helpers/shared_columns.tsx @@ -5,13 +5,15 @@ * 2.0. */ -import { setMockValues, rerender } from '../../../../../../__mocks__'; +import { setMockValues } from '../../../../../../__mocks__/kea_logic'; import '../__mocks__/engines_logic.mock'; import { ShallowWrapper } from 'enzyme'; import { EuiBasicTable, EuiButtonIcon } from '@elastic/eui'; +import { rerender } from '../../../../../../test_helpers'; + import { EnginesLogic } from '../../../../engines'; import * as engineLinkHelpers from '../engine_link_helpers'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_logic.test.ts index a67e5bb9ae7dc4..eb95d1ce148daf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__'; +import { + LogicMounter, + mockHttpValues, + mockFlashMessageHelpers, +} from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx index b326a7d3ee0759..27fe65fe518ebc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx @@ -6,12 +6,14 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions, rerender } from '../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; +import { rerender } from '../../../test_helpers'; + import { LoadingState, EmptyState } from './components'; import { EnginesTable } from './components/tables/engines_table'; import { MetaEnginesTable } from './components/tables/meta_engines_table'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/layout/kibana_header_actions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/layout/kibana_header_actions.test.tsx index 096d858cd11918..d25e6ab27b0991 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/layout/kibana_header_actions.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/layout/kibana_header_actions.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../__mocks__'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.test.tsx index fe022391d76b45..c6ccdc78b16f35 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions, mountWithIntl } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; @@ -14,7 +14,9 @@ import { shallow } from 'enzyme'; import { EuiCallOut, EuiLink } from '@elastic/eui'; -import { LogRetentionOptions } from '../'; +import { mountWithIntl } from '../../../../test_helpers'; + +import { LogRetentionOptions } from '../index'; import { LogRetentionCallout } from './'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.test.tsx index 6b5693e4c301e1..db5f058b28015a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts index 57f3f46fed92e7..4e2382c23edbde 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__'; +import { + LogicMounter, + mockHttpValues, + mockFlashMessageHelpers, +} from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.test.tsx index cd71e371089273..ab221879367b31 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.test.tsx @@ -5,12 +5,14 @@ * 2.0. */ -import { setMockValues, mountWithIntl } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; import { shallow } from 'enzyme'; +import { mountWithIntl } from '../../../../test_helpers'; + import { LogRetentionOptions } from '../types'; import { LogRetentionMessage } from './'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/meta_engine_creation.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/meta_engine_creation.test.tsx index a30f5bf77efade..fe7ea2d959289b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/meta_engine_creation.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/meta_engine_creation.test.tsx @@ -6,7 +6,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/meta_engine_creation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/meta_engine_creation_logic.test.ts index d8968316d1b720..137a8afc5c4fe0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/meta_engine_creation_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/meta_engine_creation_logic.test.ts @@ -10,7 +10,7 @@ import { mockHttpValues, mockFlashMessageHelpers, mockKibanaValues, -} from '../../../__mocks__'; +} from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/multi_input_rows/multi_input_rows.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/multi_input_rows/multi_input_rows.test.tsx index 0b6f8b4a6d3d40..3b8e1c96ff5040 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/multi_input_rows/multi_input_rows.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/multi_input_rows/multi_input_rows.test.tsx @@ -5,13 +5,15 @@ * 2.0. */ -import { setMockActions, setMockValues, rerender } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import '../../../__mocks__/shallow_useeffect.mock'; import React from 'react'; import { shallow } from 'enzyme'; +import { rerender } from '../../../test_helpers'; + import { InputRow } from './input_row'; jest.mock('./multi_input_rows_logic', () => ({ diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/multi_input_rows/multi_input_rows_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/multi_input_rows/multi_input_rows_logic.test.ts index 0e2d28a6fc3e1f..de439349bd15f5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/multi_input_rows/multi_input_rows_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/multi_input_rows/multi_input_rows_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter } from '../../../__mocks__'; +import { LogicMounter } from '../../../__mocks__/kea_logic'; import { Logic } from 'kea'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/query_tester/query_tester.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/query_tester/query_tester.test.tsx index 160be70cbbfc9c..a9e2b7129c7814 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/query_tester/query_tester.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/query_tester/query_tester.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/boost_item_content.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/boost_item_content.test.tsx index e21f46c6748dde..794c644f3d40b2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/boost_item_content.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/boost_item_content.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/functional_boost_form.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/functional_boost_form.test.tsx index feb4328e5adea1..4a540e09287ed6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/functional_boost_form.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/functional_boost_form.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/proximity_boost_form.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/proximity_boost_form.test.tsx index 0ed914abb3ab5e..776a21c5acb1b3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/proximity_boost_form.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/proximity_boost_form.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/value_boost_form.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/value_boost_form.test.tsx index 6f9284891e7113..292be35055e378 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/value_boost_form.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boost_item_content/value_boost_form.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boosts.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boosts.test.tsx index c82efa906f6760..a7c7002fbf2736 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boosts.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/boosts/boosts.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.test.tsx index 574d2ae02af999..092740ac5d3cc6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../__mocks__/kea.mock'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import '../../../__mocks__/shallow_useeffect.mock'; import '../../__mocks__/engine_logic.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.test.tsx index 8ab706f5953fbd..8384d079386784 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.test.tsx @@ -6,7 +6,7 @@ */ import '../../__mocks__/engine_logic.mock'; -import { setMockValues } from '../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_form.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_form.test.tsx index a1a241b8856a52..d4052f23cfca42 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_form.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_form.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_item_content/text_search_toggle.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_item_content/text_search_toggle.test.tsx index f2d4f9c20a58d0..85cf4af7a7b767 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_item_content/text_search_toggle.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_item_content/text_search_toggle.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_item_content/weight_slider.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_item_content/weight_slider.test.tsx index 21a112a4ea9889..49c02ef8e94f22 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_item_content/weight_slider.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_item_content/weight_slider.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../../__mocks__/kea.mock'; +import { setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_layout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_layout.test.tsx index 6f4333d94919b8..20b1a16879234e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_layout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_layout.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../__mocks__/kea.mock'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import '../../__mocks__/engine_logic.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts index 97030e08e2a9fb..1d143ed0ca9381 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../__mocks__/kea_logic'; import { mockEngineValues, mockEngineActions } from '../../__mocks__'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.test.tsx index ec6458a14b346b..b39faa60294367 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.test.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { setMockActions, setMockValues } from '../../../__mocks__/kea.mock'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx index 333cefecb99c88..1e361f113d8836 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { mockKibanaValues } from '../../../__mocks__'; +import { mockKibanaValues } from '../../../__mocks__/kea_logic'; import React from 'react'; import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/query_performance/query_performance.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/query_performance/query_performance.test.tsx index 0c62b783a47ff2..604d94f9154394 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/query_performance/query_performance.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/query_performance/query_performance.test.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { setMockValues } from '../../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.test.tsx index dd99dc6c505dab..ec521b4959535c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import '../../../__mocks__/shallow_useeffect.mock'; import '../../__mocks__/engine_logic.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_logic.test.ts index 6522d84aef1565..5ce6fd93289177 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_logic.test.ts @@ -5,8 +5,11 @@ * 2.0. */ -import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; - +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../__mocks__/kea_logic'; import { mockEngineValues } from '../../__mocks__'; import { omit } from 'lodash'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/disabled_fields_body.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/disabled_fields_body.test.tsx index db87ac20a42239..580bb4db763898 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/disabled_fields_body.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/disabled_fields_body.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/non_text_fields_body.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/non_text_fields_body.test.tsx index c99b8644812b94..8abb716183a9f0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/non_text_fields_body.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/non_text_fields_body.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/result_settings_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/result_settings_table.test.tsx index 151d436e59ea25..332b4a31895f4b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/result_settings_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/result_settings_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/text_fields_body.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/text_fields_body.test.tsx index 7be58a387fa69f..6f2f4c9f9acbfa 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/text_fields_body.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/text_fields_body.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response.test.tsx index e324150a2d52a7..964e466582d602 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts index 11f8a1089af9b5..426934b95388e1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter, mockHttpValues } from '../../../../__mocks__'; +import { LogicMounter, mockHttpValues } from '../../../../__mocks__/kea_logic'; import '../../../__mocks__/engine_logic.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mapping.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mapping.test.tsx index b7ba254cc3d7d3..0b7d4255fc3236 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mapping.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mapping.test.tsx @@ -5,9 +5,10 @@ * 2.0. */ +import '../../../__mocks__/react_router'; import '../../../__mocks__/shallow_useeffect.mock'; import { DEFAULT_INITIAL_APP_DATA } from '../../../../../common/__mocks__'; -import { setMockActions, setMockValues } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import { engines } from '../../__mocks__/engines.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.test.tsx index 9559df2c1f9815..d7ce8053c71f02 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.test.tsx @@ -6,7 +6,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.test.ts index 0faafcc7a299d1..87e6ee62460fae 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.test.ts @@ -5,8 +5,11 @@ * 2.0. */ -import { mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; -import { LogicMounter } from '../../../__mocks__/kea.mock'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../__mocks__/kea_logic'; import { engines } from '../../__mocks__/engines.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/sample_engine_creation_cta/sample_engine_creation_cta.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/sample_engine_creation_cta/sample_engine_creation_cta.test.tsx index 992afe4356a07d..ac25e887c2de05 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/sample_engine_creation_cta/sample_engine_creation_cta.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/sample_engine_creation_cta/sample_engine_creation_cta.test.tsx @@ -6,7 +6,7 @@ */ import '../../../__mocks__/enterprise_search_url.mock'; -import { setMockActions, setMockValues } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/sample_engine_creation_cta/sample_engine_creation_cta_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/sample_engine_creation_cta/sample_engine_creation_cta_logic.test.ts index 740c4df697d68b..3400361144ca48 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/sample_engine_creation_cta/sample_engine_creation_cta_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/sample_engine_creation_cta/sample_engine_creation_cta_logic.test.ts @@ -10,7 +10,7 @@ import { mockHttpValues, mockKibanaValues, mockFlashMessageHelpers, -} from '../../../__mocks__'; +} from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/meta_engines_conflicts_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/meta_engines_conflicts_table.test.tsx index eb40d70e13ff88..5d2b5c8a8eacf7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/meta_engines_conflicts_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/meta_engines_conflicts_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/meta_engines_schema_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/meta_engines_schema_table.test.tsx index 7d377d5a927143..e4235336b1d4bc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/meta_engines_schema_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/meta_engines_schema_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/schema_callouts.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/schema_callouts.test.tsx index 5bb08a6c8859a3..e259e67dd2e4ea 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/schema_callouts.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/schema_callouts.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import '../../../__mocks__/engine_logic.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/schema_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/schema_table.test.tsx index c8b0bb7ddbac5f..366558556c6f9e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/schema_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/schema_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/reindex_job/reindex_job.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/reindex_job/reindex_job.test.tsx index 1755fbea5fb7b2..e76ab60005231d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/reindex_job/reindex_job.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/reindex_job/reindex_job.test.tsx @@ -5,13 +5,12 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__'; -import '../../../../__mocks__/react_router_history.mock'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; +import { mockUseParams } from '../../../../__mocks__/react_router'; import '../../../../__mocks__/shallow_useeffect.mock'; import '../../../__mocks__/engine_logic.mock'; import React from 'react'; -import { useParams } from 'react-router-dom'; import { shallow } from 'enzyme'; @@ -38,7 +37,7 @@ describe('ReindexJob', () => { }; beforeEach(() => { - (useParams as jest.Mock).mockReturnValueOnce({ reindexJobId: 'abc1234567890' }); + mockUseParams.mockReturnValueOnce({ reindexJobId: 'abc1234567890' }); setMockValues(values); setMockActions(actions); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/reindex_job/reindex_job_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/reindex_job/reindex_job_logic.test.ts index b872ad3c914c63..f01c735aeca8e7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/reindex_job/reindex_job_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/reindex_job/reindex_job_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../../__mocks__'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../../__mocks__/kea_logic'; import '../../../__mocks__/engine_logic.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_base_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_base_logic.test.ts index 2f5788278aa0b7..684780d72a275f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_base_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_base_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../__mocks__/kea_logic'; import '../../__mocks__/engine_logic.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_logic.test.ts index 123f62af4eebad..7687296cf9f830 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../__mocks__/kea_logic'; import { mockEngineActions } from '../../__mocks__/engine_logic.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_meta_engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_meta_engine_logic.test.ts index f265fb2d74113d..4e56b26902142f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_meta_engine_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_meta_engine_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter } from '../../../__mocks__'; +import { LogicMounter } from '../../../__mocks__/kea_logic'; import { SchemaType } from '../../../shared/schema/types'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_router.test.tsx index 13a94c666509ba..f1713c36045e9d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/schema_router.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, rerender } from '../../../__mocks__'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import '../../__mocks__/engine_logic.mock'; import React from 'react'; @@ -13,6 +13,8 @@ import { Route, Switch } from 'react-router-dom'; import { shallow } from 'enzyme'; +import { rerender } from '../../../test_helpers'; + import { ReindexJob } from './reindex_job'; import { Schema, MetaEngineSchema } from './views'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/views/meta_engine_schema.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/views/meta_engine_schema.test.tsx index b1322c148b577e..1d677ad08db436 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/views/meta_engine_schema.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/views/meta_engine_schema.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import '../../../../__mocks__/shallow_useeffect.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/views/schema.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/views/schema.test.tsx index 23d1480e5dca95..91ec8eda55fc36 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/views/schema.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/views/schema.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import '../../../../__mocks__/shallow_useeffect.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search/search_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search/search_logic.test.ts index 784ebd0aad0cba..c0d81f87e3e02f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search/search_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search/search_logic.test.ts @@ -6,8 +6,11 @@ */ import '../../__mocks__/engine_logic.mock'; - -import { LogicMounter, mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__'; +import { + LogicMounter, + mockHttpValues, + mockFlashMessageHelpers, +} from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/search_ui_form.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/search_ui_form.test.tsx index 82b925f57f2dff..944c99f7c61c27 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/search_ui_form.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/search_ui_form.test.tsx @@ -9,7 +9,7 @@ jest.mock('../utils', () => ({ generatePreviewUrl: jest.fn(), })); -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/search_ui_graphic.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/search_ui_graphic.test.tsx index 0326cef9a2455f..056543fb5e748f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/search_ui_graphic.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/search_ui_graphic.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.test.tsx index 34c0669cc476eb..edec376dd3edd1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.test.tsx @@ -8,7 +8,7 @@ import '../../../__mocks__/shallow_useeffect.mock'; import '../../__mocks__/engine_logic.mock'; -import { setMockActions } from '../../../__mocks__'; +import { setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui_logic.test.ts index 2e29ac0d398a66..f615f9a4e2c720 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui_logic.test.ts @@ -5,8 +5,11 @@ * 2.0. */ -import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; - +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../__mocks__/kea_logic'; import { mockEngineValues } from '../../__mocks__'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx index 494517a4383721..fc20a9dbc5519a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx index aee23e61e76fe1..3f6bbe4307b575 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_button.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_button.test.tsx index 43a4682849c78d..fb214b267038fc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_button.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_button.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../__mocks__'; +import { setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_modal.test.tsx index 19c2f72ed6f52a..b02a21ac45aed1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_modal.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/source_engines_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/source_engines_table.test.tsx index 895c7ab35e86ac..7638db403191a4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/source_engines_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/source_engines_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { mountWithIntl, setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; @@ -13,6 +13,8 @@ import { shallow } from 'enzyme'; import { EuiInMemoryTable, EuiButtonIcon } from '@elastic/eui'; +import { mountWithIntl } from '../../../../test_helpers'; + import { SourceEnginesTable } from './source_engines_table'; describe('SourceEnginesTable', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.test.tsx index 8cfcaeec97b876..9d2fe653150c33 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import '../../../__mocks__/shallow_useeffect.mock'; import '../../__mocks__/engine_logic.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines_logic.test.ts index 49886f1257a580..c39a25276a43c3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../__mocks__/kea_logic'; import { mockRecursivelyFetchEngines } from '../../__mocks__'; import '../../__mocks__/engine_logic.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/synonym_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/synonym_card.test.tsx index ccb28a86d67c9a..7a1ba289865ee6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/synonym_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/synonym_card.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../__mocks__'; +import { setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/synonym_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/synonym_modal.test.tsx index dc2c6424bc2f99..15b74d1cdbca92 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/synonym_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/synonym_modal.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.test.tsx index 7fb3745eb158e0..c8f65c4bdbc6c4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions, rerender } from '../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import '../../../__mocks__/shallow_useeffect.mock'; import '../../__mocks__/engine_logic.mock'; @@ -16,6 +16,7 @@ import { shallow } from 'enzyme'; import { EuiPageHeader, EuiButton, EuiPagination } from '@elastic/eui'; import { Loading } from '../../../shared/loading'; +import { rerender } from '../../../test_helpers'; import { SynonymCard, SynonymModal, EmptyState } from './components'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms_logic.test.ts index 037f3d1e6912a9..630a069d0c5e8c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__'; +import { + LogicMounter, + mockHttpValues, + mockFlashMessageHelpers, +} from '../../../__mocks__/kea_logic'; import '../../__mocks__/engine_logic.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index 08aab7af164e31..4d8ff80326715b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -6,19 +6,21 @@ */ import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__'; -import { setMockValues, rerender } from '../__mocks__'; +import { setMockValues } from '../__mocks__/kea_logic'; +import { mockUseRouteMatch } from '../__mocks__/react_router'; import '../__mocks__/shallow_useeffect.mock'; import '../__mocks__/enterprise_search_url.mock'; -import '../__mocks__/react_router_history.mock'; import React from 'react'; -import { Redirect, useRouteMatch } from 'react-router-dom'; +import { Redirect } from 'react-router-dom'; import { shallow, ShallowWrapper } from 'enzyme'; import { Layout, SideNav, SideNavLink } from '../shared/layout'; +import { rerender } from '../test_helpers'; + jest.mock('./app_logic', () => ({ AppLogic: jest.fn() })); import { AppLogic } from './app_logic'; @@ -184,14 +186,14 @@ describe('AppSearchNav', () => { const getEnginesLink = (wrapper: ShallowWrapper) => wrapper.find(SideNavLink).dive(); it('does not render the engine subnav on top-level routes', () => { - (useRouteMatch as jest.Mock).mockReturnValueOnce(false); + mockUseRouteMatch.mockReturnValueOnce(false); const wrapper = shallow(); expect(getEnginesLink(wrapper).find(EngineNav)).toHaveLength(0); }); it('renders the engine subnav if currently on an engine route', () => { - (useRouteMatch as jest.Mock).mockReturnValueOnce(true); + mockUseRouteMatch.mockReturnValueOnce(true); const wrapper = shallow(); expect(getEnginesLink(wrapper).find(EngineNav)).toHaveLength(1); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/encode_path_params/index.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/encode_path_params/index.test.ts index 88863e83f9b671..f7464d18612654 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/encode_path_params/index.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/encode_path_params/index.test.ts @@ -5,8 +5,7 @@ * 2.0. */ -import '../../../__mocks__/react_router_history.mock'; -import { useParams } from 'react-router-dom'; +import { mockUseParams } from '../../../__mocks__/react_router'; import { encodePathParams, generateEncodedPath, useDecodedParams } from './'; @@ -38,7 +37,7 @@ describe('generateEncodedPath', () => { describe('useDecodedParams', () => { it('decodeURIComponent()s all object values from useParams()', () => { - (useParams as jest.Mock).mockReturnValue({ + mockUseParams.mockReturnValue({ someValue: 'hello%20world%3F%3F%3F', anotherValue: 'test!%40%23%24%25%5E%26*%5B%5D%2F%7C%3B%3A%22%3C%3E~%60', }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/formatted_date_time/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/formatted_date_time/index.test.tsx index 5137a60ffe59d0..47d1fe6b69d560 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/formatted_date_time/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/formatted_date_time/index.test.tsx @@ -5,10 +5,10 @@ * 2.0. */ -import { mountWithIntl } from '../../../__mocks__'; - import React from 'react'; +import { mountWithIntl } from '../../../test_helpers'; + import { FormattedDateTime } from './'; describe('FormattedDateTime', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/recursively_fetch_engines/index.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/recursively_fetch_engines/index.test.ts index 104f98e45a5f57..a73dd075115eed 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/recursively_fetch_engines/index.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/recursively_fetch_engines/index.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; +import { mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/license_callout/license_callout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/license_callout/license_callout.test.tsx index 26892f7cec7ae7..0c77a0fbf6f5af 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/license_callout/license_callout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/license_callout/license_callout.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../__mocks__'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx index 8631e6e2a51d41..9d54a9f1725e9e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, mockTelemetryActions } from '../../../__mocks__'; +import { setMockValues, mockTelemetryActions } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx index 9c0f7c2bac94be..90e16fe2d22fad 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../__mocks__/kea.mock'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/trial_callout/trial_callout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/trial_callout/trial_callout.test.tsx index 2ed2f9e43e9c41..72958acacb0348 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/trial_callout/trial_callout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/trial_callout/trial_callout.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../__mocks__'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx index 2d8dbd55f4366a..fbb3e58f198a73 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx @@ -5,12 +5,14 @@ * 2.0. */ -import { setMockValues, rerender } from '../__mocks__'; +import { setMockValues } from '../__mocks__/kea_logic'; import React from 'react'; import { shallow } from 'enzyme'; +import { rerender } from '../test_helpers'; + import { ErrorConnecting } from './components/error_connecting'; import { ProductSelector } from './components/product_selector'; import { SetupGuide } from './components/setup_guide'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx index d9d31f5a45d4be..e8f0816de5225e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import '../../__mocks__/kea.mock'; +import '../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.test.tsx index 289dcc0137cb84..6f4f3853fa8c96 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../__mocks__/kea.mock'; +import { setMockValues, setMockActions } from '../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.test.ts index c7dc658dada74c..19e236ac122f04 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { mockKibanaValues } from '../../__mocks__/kibana_logic.mock'; +import { mockKibanaValues } from '../../__mocks__/kea_logic/kibana_logic.mock'; import { resetContext } from 'kea'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts index b6b0e23ce7d6a3..b361e796b4f439 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import '../../__mocks__/kibana_logic.mock'; +import '../../__mocks__/kea_logic/kibana_logic.mock'; import { FlashMessagesLogic } from './flash_messages_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/set_message_helpers.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/set_message_helpers.test.ts index d22be32e038cb3..6d56c7b202797c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/set_message_helpers.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/set_message_helpers.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import '../../__mocks__/kibana_logic.mock'; +import '../../__mocks__/kea_logic/kibana_logic.mock'; import { FlashMessagesLogic } from './flash_messages_logic'; import { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts index a5f54d16b2fad8..4cc907c3de9e4c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { mockKibanaValues } from '../../__mocks__'; +import { mockKibanaValues } from '../../__mocks__/kea_logic'; import { resetContext } from 'kea'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts index c05c4dcbdddc00..f5d10ba4bc00f8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { setMockValues, mockKibanaValues, mockHistory } from '../../__mocks__'; +import { setMockValues, mockKibanaValues } from '../../__mocks__/kea_logic'; +import { mockHistory } from '../../__mocks__/react_router'; jest.mock('../react_router_helpers', () => ({ letBrowserHandleEvent: jest.fn(() => false), diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx index c9743e6824018c..d396aba8955873 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx @@ -6,7 +6,8 @@ */ import '../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, mockKibanaValues, mockHistory } from '../../__mocks__'; +import { setMockValues, mockKibanaValues } from '../../__mocks__/kea_logic'; +import { mockHistory } from '../../__mocks__/react_router'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.test.tsx index 451b49738029dc..244037d6e13820 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.test.tsx @@ -5,10 +5,9 @@ * 2.0. */ -import '../../__mocks__/react_router_history.mock'; +import { mockLocation } from '../../__mocks__/react_router'; import React from 'react'; -import { useLocation } from 'react-router-dom'; import { shallow } from 'enzyme'; @@ -63,7 +62,7 @@ describe('SideNavLink', () => { }); it('sets an active class if the current path matches the nav link', () => { - (useLocation as jest.Mock).mockImplementationOnce(() => ({ pathname: '/test/' })); + mockLocation.pathname = '/test/'; const wrapper = shallow(Link); @@ -71,7 +70,7 @@ describe('SideNavLink', () => { }); it('sets an active class if the current path is / and the link isRoot', () => { - (useLocation as jest.Mock).mockImplementationOnce(() => ({ pathname: '/' })); + mockLocation.pathname = '/'; const wrapper = shallow( @@ -111,7 +110,7 @@ describe('SideNavLink', () => { describe('shouldShowActiveForSubroutes', () => { it("won't set an active class when route is a subroute of 'to'", () => { - (useLocation as jest.Mock).mockImplementationOnce(() => ({ pathname: '/documents/1234' })); + mockLocation.pathname = '/documents/1234'; const wrapper = shallow( @@ -123,7 +122,7 @@ describe('SideNavLink', () => { }); it('sets an active class if the current path is a subRoute of "to", and shouldShowActiveForSubroutes is true', () => { - (useLocation as jest.Mock).mockImplementationOnce(() => ({ pathname: '/documents/1234' })); + mockLocation.pathname = '/documents/1234'; const wrapper = shallow( diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx index 7e75b2b47bb7ad..1561224a26e422 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../__mocks__/kea.mock'; +import { setMockValues } from '../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts index fe2973cfdee325..2ffe87279d44f3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { mockHistory } from '../../__mocks__'; +import { mockHistory } from '../../__mocks__/react_router'; import { httpServiceMock } from 'src/core/public/mocks'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.test.tsx index 75639ffeb9d6b5..7fded20cdd87e6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.test.tsx @@ -5,9 +5,8 @@ * 2.0. */ -import '../../__mocks__/kea.mock'; - -import { mockKibanaValues, mockHistory } from '../../__mocks__'; +import { mockKibanaValues } from '../../__mocks__/kea_logic'; +import { mockHistory } from '../../__mocks__/react_router'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.test.tsx index 0136f9745c3224..58b6bc8a6c4853 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.test.tsx @@ -5,14 +5,14 @@ * 2.0. */ -import { mountWithIntl } from '../../../__mocks__'; - import React from 'react'; import { shallow } from 'enzyme'; import { EuiSteps, EuiLink } from '@elastic/eui'; +import { mountWithIntl } from '../../../test_helpers'; + import { CloudSetupInstructions } from './instructions'; describe('CloudSetupInstructions', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.test.tsx index fd31ca720b82b1..9f65e6b599a98d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.test.tsx @@ -5,14 +5,14 @@ * 2.0. */ -import { mountWithIntl } from '../../__mocks__'; - import React from 'react'; import { shallow } from 'enzyme'; import { EuiSteps, EuiLink } from '@elastic/eui'; +import { mountWithIntl } from '../../test_helpers'; + import { SetupInstructions } from './instructions'; describe('SetupInstructions', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx index 90ddddd7d20aa0..e33b9d29689c47 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, rerender } from '../../__mocks__'; +import { setMockValues } from '../../__mocks__/kea_logic'; import React from 'react'; @@ -13,6 +13,8 @@ import { shallow, ShallowWrapper } from 'enzyme'; import { EuiIcon } from '@elastic/eui'; +import { rerender } from '../../test_helpers'; + import { CloudSetupInstructions } from './cloud/instructions'; import { SetupInstructions } from './instructions'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx index 5fc8074d0a4d78..bd9b7fb5bfbe33 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx @@ -6,7 +6,7 @@ */ import '../../__mocks__/shallow_useeffect.mock'; -import { mockTelemetryActions } from '../../__mocks__'; +import { mockTelemetryActions } from '../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts index e516daedc1ba68..d80750d068f2b5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter, mockHttpValues } from '../../__mocks__'; +import { LogicMounter, mockHttpValues } from '../../__mocks__/kea_logic'; import { JSON_HEADER as headers } from '../../../../common/constants'; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/enzyme_rerender.mock.ts b/x-pack/plugins/enterprise_search/public/applications/test_helpers/enzyme_rerender.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/enzyme_rerender.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/test_helpers/enzyme_rerender.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/expected_async_error.ts b/x-pack/plugins/enterprise_search/public/applications/test_helpers/expected_async_error.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/expected_async_error.ts rename to x-pack/plugins/enterprise_search/public/applications/test_helpers/expected_async_error.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/test_helpers/index.ts b/x-pack/plugins/enterprise_search/public/applications/test_helpers/index.ts new file mode 100644 index 00000000000000..e34ff763637b5a --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/test_helpers/index.ts @@ -0,0 +1,15 @@ +/* + * 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. + */ + +// Enzyme helpers +export { mountAsync } from './mount_async'; +export { mountWithIntl } from './mount_with_i18n'; +export { shallowWithIntl } from './shallow_with_i18n'; +export { rerender } from './enzyme_rerender'; + +// Misc +export { expectedAsyncError } from './expected_async_error'; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/test_helpers/mount_async.tsx similarity index 96% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx rename to x-pack/plugins/enterprise_search/public/applications/test_helpers/mount_async.tsx index 886effcd540573..cd66c0ae85a918 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/test_helpers/mount_async.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import { mountWithIntl } from './mount_with_i18n.mock'; - import React from 'react'; import { mount, ReactWrapper } from 'enzyme'; import { act } from 'react-dom/test-utils'; +import { mountWithIntl } from './mount_with_i18n'; + /** * This helper is intended for components that have async effects * (e.g. http fetches) on mount. It mostly adds act/update boilerplate diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/test_helpers/mount_with_i18n.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx rename to x-pack/plugins/enterprise_search/public/applications/test_helpers/mount_with_i18n.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_with_i18n.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/test_helpers/shallow_with_i18n.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_with_i18n.mock.tsx rename to x-pack/plugins/enterprise_search/public/applications/test_helpers/shallow_with_i18n.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts index 34e67acc870eea..b2cc835da4ecd5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts @@ -6,7 +6,7 @@ */ import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__'; -import { LogicMounter } from '../__mocks__'; +import { LogicMounter } from '../__mocks__/kea_logic'; import { AppLogic } from './app_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/account_header/account_header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/account_header/account_header.test.tsx index e8035f01a94057..9df11ab2308da6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/account_header/account_header.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/account_header/account_header.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx index 0bced6a7fc4e00..e605e914df061f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx @@ -5,8 +5,7 @@ * 2.0. */ -import '../../../../__mocks__/kea.mock'; -import { mockTelemetryActions } from '../../../../__mocks__'; +import { mockTelemetryActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx index 2c2859e8f4427d..fb0ea822206400 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx @@ -5,8 +5,9 @@ * 2.0. */ +import '../__mocks__/react_router'; import '../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions, mockKibanaValues } from '../__mocks__'; +import { setMockValues, setMockActions, mockKibanaValues } from '../__mocks__/kea_logic'; import React from 'react'; import { Redirect } from 'react-router-dom'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.test.tsx index 0ee872f7cfe8ab..92cbfcf6eeafe4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.test.tsx @@ -6,7 +6,11 @@ */ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { mockKibanaValues, setMockActions, setMockValues } from '../../../../../__mocks__'; +import { + mockKibanaValues, + setMockActions, + setMockValues, +} from '../../../../../__mocks__/kea_logic'; import { sourceConfigData } from '../../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx index 90da349ea4f270..6bf71cd73ec354 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; import { contentSources, configuredSources, diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts index b52b354a6b1150..fcaa847c47f3eb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts @@ -10,7 +10,7 @@ import { mockFlashMessageHelpers, mockHttpValues, mockKibanaValues, -} from '../../../../../__mocks__'; +} from '../../../../../__mocks__/kea_logic'; import { sourceConfigData } from '../../../../__mocks__/content_sources.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx index fcb55f24ddb037..26a3d38f247ea0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues } from '../../../../../__mocks__'; +import { setMockValues } from '../../../../../__mocks__/kea_logic'; import { mergedAvailableSources } from '../../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx index 099989255bf477..6c0d87b7696ecd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx index 533dfcda70db1e..332456cae99ad0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx index d6b427630e48e1..d8696118d7f4e7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/reauthenticate.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/reauthenticate.test.tsx index c38ab167b18de8..b826b8b42232e7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/reauthenticate.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/reauthenticate.test.tsx @@ -5,8 +5,9 @@ * 2.0. */ +import '../../../../../__mocks__/react_router'; import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx index c0f7f1139cb734..32e1c59c56293b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; import { sourceConfigData } from '../../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx index cd8ba37695ac66..6afac428f2866c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx @@ -5,12 +5,14 @@ * 2.0. */ -import { mountAsync, setMockValues } from '../../../../../__mocks__'; +import { setMockValues } from '../../../../../__mocks__/kea_logic'; import React from 'react'; import { EuiPanel } from '@elastic/eui'; +import { mountWithIntl } from '../../../../../test_helpers'; + import { staticSourceData } from '../../source_data'; import { SourceFeatures } from './source_features'; @@ -26,7 +28,7 @@ describe('SourceFeatures', () => { it('renders hasPlatinumLicense & isOrganization', async () => { setMockValues({ hasPlatinumLicense: true, isOrganization: true }); - const wrapper = await mountAsync(, { i18n: true }); + const wrapper = await mountWithIntl(); expect(wrapper.find('FeaturesRouter[featureId="SyncFrequency"]')).toHaveLength(1); expect(wrapper.find('FeaturesRouter[featureId="SyncedItems"]')).toHaveLength(1); @@ -34,7 +36,7 @@ describe('SourceFeatures', () => { it('renders !hasPlatinumLicense & isOrganization', async () => { setMockValues({ hasPlatinumLicense: false, isOrganization: true }); - const wrapper = await mountAsync(, { i18n: true }); + const wrapper = await mountWithIntl(); expect(wrapper.find('FeaturesRouter[featureId="SyncFrequency"]')).toHaveLength(1); expect(wrapper.find('FeaturesRouter[featureId="SyncedItems"]')).toHaveLength(1); @@ -43,7 +45,7 @@ describe('SourceFeatures', () => { it('renders hasPlatinumLicense & !isOrganization', async () => { setMockValues({ hasPlatinumLicense: true, isOrganization: false }); - const wrapper = await mountAsync(, { i18n: true }); + const wrapper = await mountWithIntl(); expect(wrapper.find('FeaturesRouter[featureId="Private"]')).toHaveLength(1); expect(wrapper.find('FeaturesRouter[featureId="SyncedItems"]')).toHaveLength(1); @@ -52,7 +54,7 @@ describe('SourceFeatures', () => { it('renders !hasPlatinumLicense & !isOrganization', async () => { setMockValues({ hasPlatinumLicense: false, isOrganization: false }); - const wrapper = await mountAsync(, { i18n: true }); + const wrapper = await mountWithIntl(); expect(wrapper.find('IncludedFeatures').find(EuiPanel)).toHaveLength(0); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.test.tsx index 54be43596a4314..aa5cec385738d2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.test.tsx @@ -7,7 +7,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import { exampleResult } from '../../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts index 5a6ef5ba5990f1..10c715c80b3d66 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts @@ -10,7 +10,7 @@ import { mockFlashMessageHelpers, mockHttpValues, mockKibanaValues, -} from '../../../../../__mocks__'; +} from '../../../../../__mocks__/kea_logic'; import { exampleResult } from '../../../../__mocks__/content_sources.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.test.tsx index f04afe60aa49d6..7f4e566022ab42 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.test.tsx @@ -7,7 +7,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues } from '../../../../../__mocks__'; +import { setMockValues } from '../../../../../__mocks__/kea_logic'; import React from 'react'; import { Route, Switch } from 'react-router-dom'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx index 15e1fe0ed417c8..82a421d85df01c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx @@ -7,7 +7,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues } from '../../../../../__mocks__'; +import { setMockValues } from '../../../../../__mocks__/kea_logic'; import { exampleResult } from '../../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx index 6f90c1045ae31e..7139ea30be137a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx @@ -7,7 +7,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues } from '../../../../../__mocks__'; +import { setMockValues } from '../../../../../__mocks__/kea_logic'; import { exampleResult } from '../../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.test.tsx index 49845e79d86aad..a38e0ce82490d6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.test.tsx @@ -7,7 +7,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues } from '../../../../../__mocks__'; +import { setMockValues } from '../../../../../__mocks__/kea_logic'; import { exampleResult } from '../../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.test.tsx index fe7bced8438418..7d828549178e02 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.test.tsx @@ -7,7 +7,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import { exampleResult } from '../../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.test.tsx index 768573ce80feed..f400527c6c0039 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.test.tsx @@ -6,7 +6,7 @@ */ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import { exampleResult } from '../../../../__mocks__/content_sources.mock'; /** diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.test.tsx index 28de0006f162f6..cc0378b4b70db0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.test.tsx @@ -7,7 +7,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import { exampleResult } from '../../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx index a30f1bfbd596a8..f2cf5f50b813b4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx @@ -7,7 +7,7 @@ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import { fullContentSources } from '../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx index 6b656fbdc6ddb5..178c9125ee4370 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx @@ -7,7 +7,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import { mostRecentIndexJob } from '../../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.test.tsx index f600d089c6e06a..fdb729b59b0972 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.test.tsx @@ -5,12 +5,11 @@ * 2.0. */ +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; +import { mockUseParams } from '../../../../../__mocks__/react_router'; import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../../__mocks__'; - import React from 'react'; -import { useParams } from 'react-router-dom'; import { shallow } from 'enzyme'; @@ -27,7 +26,7 @@ describe('SchemaChangeErrors', () => { setMockValues({ fieldCoercionErrors, serverSchema }); setMockActions({ initializeSchemaFieldErrors: jest.fn() }); - (useParams as jest.Mock).mockImplementationOnce(() => ({ + mockUseParams.mockImplementationOnce(() => ({ activeReindexJobId: '1', sourceId: '123', })); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.test.tsx index 9996e58e819b23..c2c364763e2ebb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.test.tsx @@ -7,7 +7,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.test.ts index 650909c0b5a82e..fd1a574b3438f6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../../../__mocks__'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../../../__mocks__/kea_logic'; import { mostRecentIndexJob } from '../../../../__mocks__/content_sources.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.test.tsx index 9eecc41aa17780..a182c2697fe90e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.test.tsx @@ -5,9 +5,9 @@ * 2.0. */ +import '../../../../__mocks__/react_router'; import '../../../../__mocks__/shallow_useeffect.mock'; - -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; import { useLocation } from 'react-router-dom'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.test.tsx index 8aa644827709aa..4bcc4b16166d18 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.test.tsx @@ -7,7 +7,7 @@ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import { fullContentSources, contentItems } from '../../../__mocks__/content_sources.mock'; import { meta } from '../../../__mocks__/meta.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.test.tsx index b2a4488b04107c..74f32cc22c2a8c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.test.tsx @@ -7,7 +7,7 @@ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import { fullContentSources, sourceConfigData } from '../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.test.tsx index 59f3bfb0a5611d..25c389419d731e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.test.tsx index b986658f19fb31..9df91406c4b7b4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.test.tsx @@ -6,8 +6,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; - -import { setMockValues, setMockActions } from '../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import { contentSources } from '../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources.test.tsx index e6f19ff13b3ccf..08f560c984344d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources.test.tsx @@ -7,7 +7,7 @@ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.test.tsx index 7558eb1e4e6621..6af439814b8918 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.test.tsx @@ -7,7 +7,7 @@ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues } from '../../../__mocks__'; +import { setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts index 2cf867446b7fb2..03f46830fafc3e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts @@ -10,12 +10,12 @@ import { mockFlashMessageHelpers, mockHttpValues, mockKibanaValues, - expectedAsyncError, -} from '../../../__mocks__'; +} from '../../../__mocks__/kea_logic'; import { fullContentSources, contentItems } from '../../__mocks__/content_sources.mock'; import { meta } from '../../__mocks__/meta.mock'; import { DEFAULT_META } from '../../../shared/constants'; +import { expectedAsyncError } from '../../../test_helpers'; jest.mock('../../app_logic', () => ({ AppLogic: { values: { isOrganization: true } }, diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.test.tsx index dda3eeea549264..783fc434fe8e5d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.test.tsx @@ -7,13 +7,12 @@ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../__mocks__'; -import { mockLocation } from '../../../__mocks__/react_router_history.mock'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; +import { mockLocation, mockUseParams } from '../../../__mocks__/react_router'; import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock'; import { contentSources } from '../../__mocks__/content_sources.mock'; import React from 'react'; -import { useParams } from 'react-router-dom'; import { Route, Switch } from 'react-router-dom'; import { shallow } from 'enzyme'; @@ -46,7 +45,7 @@ describe('SourceRouter', () => { resetSourceState, }); setMockValues({ ...mockValues }); - (useParams as jest.Mock).mockImplementationOnce(() => ({ + mockUseParams.mockImplementationOnce(() => ({ sourceId: contentSource.id, })); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts index 13844f51b2319d..74d3faca5994bc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts @@ -9,10 +9,11 @@ import { LogicMounter, mockFlashMessageHelpers, mockHttpValues, - expectedAsyncError, -} from '../../../__mocks__'; +} from '../../../__mocks__/kea_logic'; import { configuredSources, contentSources } from '../../__mocks__/content_sources.mock'; +import { expectedAsyncError } from '../../../test_helpers'; + jest.mock('../../app_logic', () => ({ AppLogic: { values: { isOrganization: true } }, })); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx index eac1bd7d3ea277..3ba5161e5a3e3a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx @@ -5,9 +5,9 @@ * 2.0. */ +import '../../../__mocks__/react_router'; import '../../../__mocks__/shallow_useeffect.mock'; - -import { setMockValues, setMockActions } from '../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; import { Route, Switch, Redirect } from 'react-router-dom'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.test.tsx index 06d7ecff502992..507e66bdf0332d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.test.tsx @@ -7,7 +7,7 @@ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx index 784544b0001fa0..7468f9c9379435 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx index 9118bc5e7adf33..dd4b22c6ca62cc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../__mocks__'; +import { setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx index 1813b766b9875c..dc7e635d8fa6b1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions } from '../../../../__mocks__'; +import { setMockActions } from '../../../../__mocks__/kea_logic'; import { users } from '../../../__mocks__/users.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx index 7c39414f158eff..5619698335b30a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import { contentSources } from '../../../__mocks__/content_sources.mock'; import { groups } from '../../../__mocks__/groups.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx index 8d5714fd057929..7f60b8d8584bad 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import { groups } from '../../../__mocks__/groups.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx index 205eafd69cd10e..7915482a45b2a4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import { groups } from '../../../__mocks__/groups.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx index e75b325a4eae92..1116c625be07a1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import { users } from '../../../__mocks__/users.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx index 4a9244486bf307..0faeb1df5398c9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import { groups } from '../../../__mocks__/groups.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx index e4dde81949bfaa..263ec5f1b27c0d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx index a6376d76536276..0dde2f5eaf7f70 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import { groups } from '../../../__mocks__/groups.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx index f60a13ec296d59..d11b830a8fc4b5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import { groups } from '../../../__mocks__/groups.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx index 49d51dfc7254c8..5256155979e4d3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import { users } from '../../../__mocks__/users.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx index dd72850a06ad97..02f0b53af97cc3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import { groups } from '../../../__mocks__/groups.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx index 1e2a57da9ad2e5..4150604fb80794 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import { contentSources } from '../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx index e472563862015f..93e5ad69964ca9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import { users } from '../../../__mocks__/users.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx index bcc58c394b5161..83a20efe5257eb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts index 9f12e8f202d506..2c9ca642f2283e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts @@ -10,7 +10,7 @@ import { mockKibanaValues, mockFlashMessageHelpers, mockHttpValues, -} from '../../../__mocks__'; +} from '../../../__mocks__/kea_logic'; import { groups } from '../../__mocks__/groups.mock'; import { mockGroupValues } from './__mocks__/group_logic.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx index 0b218f24961549..4c13dbce3ef1e6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx @@ -5,8 +5,9 @@ * 2.0. */ +import '../../../__mocks__/react_router'; import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import { groups } from '../../__mocks__/groups.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx index 54f8580a8eab97..2929fa0ff1d618 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx @@ -6,7 +6,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import { groups } from '../../__mocks__/groups.mock'; import { meta } from '../../__mocks__/meta.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts index bb6e7c0c76faf9..c4a860368ff8be 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../__mocks__/kea_logic'; import { contentSources } from '../../__mocks__/content_sources.mock'; import { groups } from '../../__mocks__/groups.mock'; import { users } from '../../__mocks__/users.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx index 0295605eddd4d2..66204f74f51f18 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx @@ -6,7 +6,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions } from '../../../__mocks__'; +import { setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; import { Route, Switch } from 'react-router-dom'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/overview_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/overview_logic.mock.ts index 787354974cb31c..9aaa6253ea0aba 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/overview_logic.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/overview_logic.mock.ts @@ -6,7 +6,7 @@ */ import { DEFAULT_INITIAL_APP_DATA } from '../../../../../../common/__mocks__'; -import { setMockValues as setMockKeaValues, setMockActions } from '../../../../__mocks__/kea.mock'; +import { setMockValues as setMockKeaValues, setMockActions } from '../../../../__mocks__/kea_logic'; const { workplaceSearch: mockAppValues } = DEFAULT_INITIAL_APP_DATA; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx index 2b9dc98b035671..382eb676f87081 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx @@ -5,9 +5,8 @@ * 2.0. */ -import '../../../__mocks__/kea.mock'; import '../../../__mocks__/enterprise_search_url.mock'; -import { mockTelemetryActions } from '../../../__mocks__'; +import { mockTelemetryActions } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx index 5059533519a6fe..01e5245c597eb9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { mockTelemetryActions } from '../../../__mocks__'; +import { mockTelemetryActions } from '../../../__mocks__/kea_logic'; import { setMockValues } from './__mocks__'; import './__mocks__/overview_logic.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx index 19c893bec81eaf..f4fa1dab89810e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import '../../../__mocks__/react_router_history.mock'; import './__mocks__/overview_logic.mock'; import { mockActions, setMockValues } from './__mocks__'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.test.ts index 75a41216ffbb72..090715e14309a1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LogicMounter, mockHttpValues } from '../../../__mocks__'; +import { LogicMounter, mockHttpValues } from '../../../__mocks__/kea_logic'; import { mockOverviewValues } from './__mocks__'; import { OverviewLogic } from './overview_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx index 3a925f011cc188..0cb3f77c681a13 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { mockTelemetryActions } from '../../../__mocks__'; +import { mockTelemetryActions } from '../../../__mocks__/kea_logic'; import { setMockValues } from './__mocks__'; import './__mocks__/overview_logic.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mapping.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mapping.test.tsx index 01981b1c3894e8..619a931864500a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mapping.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mapping.test.tsx @@ -5,8 +5,9 @@ * 2.0. */ +import '../../../__mocks__/react_router'; import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings.test.tsx index 9559df2c1f9815..d7ce8053c71f02 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings.test.tsx @@ -6,7 +6,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions, setMockValues } from '../../../__mocks__'; +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.test.ts index 281e3cfdff1c17..716cb8ebb6d47d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.test.ts @@ -5,8 +5,11 @@ * 2.0. */ -import { mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__'; -import { LogicMounter } from '../../../__mocks__/kea.mock'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../__mocks__/kea_logic'; import { groups } from '../../__mocks__/groups.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.test.tsx index 4f7160ba631f18..65f9ac9cbb0f92 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__'; +import { setMockValues } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.test.tsx index 346994ac557f9a..c9720eb6c1c042 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.test.tsx @@ -6,7 +6,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.test.ts index 02d8fdd3c30e48..ecb97cea528b94 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.test.ts @@ -5,8 +5,11 @@ * 2.0. */ -import { mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__'; -import { LogicMounter } from '../../../__mocks__/kea.mock'; +import { + LogicMounter, + mockHttpValues, + mockFlashMessageHelpers, +} from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.test.tsx index 13ef86a21a208f..e95dd60ae6089f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.test.tsx @@ -7,7 +7,7 @@ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import { configuredSources } from '../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.test.tsx index ed05829d9e082d..15d0db4c415d00 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.test.tsx @@ -7,7 +7,7 @@ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx index 55a58610e0ed69..3c0cae212caa42 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx @@ -7,7 +7,7 @@ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import { oauthApplication } from '../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.test.tsx index ed9f715fd69163..c9b458e8d3535f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.test.tsx @@ -7,7 +7,7 @@ import '../../../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import { sourceConfigData } from '../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.test.ts index a57c2c1f9ad443..0aef84ccf20e2b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.test.ts @@ -5,8 +5,12 @@ * 2.0. */ -import { mockFlashMessageHelpers, mockHttpValues, mockKibanaValues } from '../../../__mocks__'; -import { LogicMounter } from '../../../__mocks__/kea.mock'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, + mockKibanaValues, +} from '../../../__mocks__/kea_logic'; import { configuredSources, oauthApplication } from '../../__mocks__/content_sources.mock'; import { nextTick } from '@kbn/test/jest'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.test.tsx index 3c0dee2a874aea..6a9104ceefde04 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.test.tsx @@ -7,7 +7,7 @@ import '../../../__mocks__/shallow_useeffect.mock'; -import { setMockActions } from '../../../__mocks__'; +import { setMockActions } from '../../../__mocks__/kea_logic'; import React from 'react'; import { Route, Redirect, Switch } from 'react-router-dom'; diff --git a/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts b/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts index 0d4d117b69bf30..e7d3ef97a301b4 100644 --- a/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts +++ b/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts @@ -41,6 +41,8 @@ type AggResultsResponse = { key?: number } & { }; }; +const TIME_RANGE_PADDING = 10; + /** * Mapping for result types and corresponding score fields. */ @@ -63,43 +65,6 @@ export function alertingServiceProvider(mlClient: MlClient, datafeedsService: Da }; }; - const getCommonScriptedFields = () => { - return { - start: { - script: { - lang: 'painless', - source: `LocalDateTime.ofEpochSecond((doc["timestamp"].value.getMillis()-((doc["bucket_span"].value * 1000) - * params.padding)) / 1000, 0, ZoneOffset.UTC).toString()+\":00.000Z\"`, - params: { - padding: 10, - }, - }, - }, - end: { - script: { - lang: 'painless', - source: `LocalDateTime.ofEpochSecond((doc["timestamp"].value.getMillis()+((doc["bucket_span"].value * 1000) - * params.padding)) / 1000, 0, ZoneOffset.UTC).toString()+\":00.000Z\"`, - params: { - padding: 10, - }, - }, - }, - timestamp_epoch: { - script: { - lang: 'painless', - source: 'doc["timestamp"].value.getMillis()/1000', - }, - }, - timestamp_iso8601: { - script: { - lang: 'painless', - source: 'doc["timestamp"].value', - }, - }, - }; - }; - /** * Builds an agg query based on the requested result type. * @param resultType @@ -110,9 +75,9 @@ export function alertingServiceProvider(mlClient: MlClient, datafeedsService: Da severity: number, useInitialScore?: boolean ) => { - const influencerScoreField = `${useInitialScore ? 'initial_' : ''}influencer_score`; - const recordScoreField = `${useInitialScore ? 'initial_' : ''}record_score`; - const bucketScoreField = `${useInitialScore ? 'initial_' : ''}anomaly_score`; + const influencerScoreField = getScoreFields(ANOMALY_RESULT_TYPE.INFLUENCER, useInitialScore); + const recordScoreField = getScoreFields(ANOMALY_RESULT_TYPE.RECORD, useInitialScore); + const bucketScoreField = getScoreFields(ANOMALY_RESULT_TYPE.BUCKET, useInitialScore); return { influencer_results: { @@ -140,27 +105,13 @@ export function alertingServiceProvider(mlClient: MlClient, datafeedsService: Da 'influencer_field_name', 'influencer_field_value', 'influencer_score', + 'initial_influencer_score', 'is_interim', 'job_id', + 'bucket_span', ], }, size: 3, - script_fields: { - ...getCommonScriptedFields(), - score: { - script: { - lang: 'painless', - source: `Math.floor(doc["${influencerScoreField}"].value)`, - }, - }, - unique_key: { - script: { - lang: 'painless', - source: - 'doc["timestamp"].value + "_" + doc["influencer_field_name"].value + "_" + doc["influencer_field_value"].value', - }, - }, - }, }, }, }, @@ -188,6 +139,7 @@ export function alertingServiceProvider(mlClient: MlClient, datafeedsService: Da 'result_type', 'timestamp', 'record_score', + 'initial_record_score', 'is_interim', 'function', 'field_name', @@ -199,24 +151,10 @@ export function alertingServiceProvider(mlClient: MlClient, datafeedsService: Da 'partition_field_value', 'job_id', 'detector_index', + 'bucket_span', ], }, size: 3, - script_fields: { - ...getCommonScriptedFields(), - score: { - script: { - lang: 'painless', - source: `Math.floor(doc["${recordScoreField}"].value)`, - }, - }, - unique_key: { - script: { - lang: 'painless', - source: 'doc["timestamp"].value + "_" + doc["function"].value', - }, - }, - }, }, }, }, @@ -247,25 +185,12 @@ export function alertingServiceProvider(mlClient: MlClient, datafeedsService: Da 'result_type', 'timestamp', 'anomaly_score', + 'initial_anomaly_score', 'is_interim', + 'bucket_span', ], }, size: 1, - script_fields: { - ...getCommonScriptedFields(), - score: { - script: { - lang: 'painless', - source: `Math.floor(doc["${bucketScoreField}"].value)`, - }, - }, - unique_key: { - script: { - lang: 'painless', - source: 'doc["timestamp"].value', - }, - }, - }, }, }, }, @@ -282,6 +207,10 @@ export function alertingServiceProvider(mlClient: MlClient, datafeedsService: Da return source.job_id; }; + const getScoreFields = (resultType: AnomalyResultType, useInitialScore?: boolean) => { + return `${useInitialScore ? 'initial_' : ''}${resultTypeScoreMapping[resultType]}`; + }; + const getRecordKey = (source: AnomalyRecordDoc): string => { let alertInstanceKey = `${source.job_id}_${source.timestamp}`; @@ -294,18 +223,23 @@ export function alertingServiceProvider(mlClient: MlClient, datafeedsService: Da return alertInstanceKey; }; - const getResultsFormatter = (resultType: AnomalyResultType) => { + /** + * Returns a callback for formatting elasticsearch aggregation response + * to the alert context. + * @param resultType + */ + const getResultsFormatter = (resultType: AnomalyResultType, useInitialScore: boolean = false) => { const resultsLabel = getAggResultsLabel(resultType); return (v: AggResultsResponse): AlertExecutionResult | undefined => { const aggTypeResults = v[resultsLabel.aggGroupLabel]; if (aggTypeResults.doc_count === 0) { return; } - const requestedAnomalies = aggTypeResults[resultsLabel.topHitsLabel].hits.hits; - const topAnomaly = requestedAnomalies[0]; const alertInstanceKey = getAlertInstanceKey(topAnomaly._source); + const timestamp = topAnomaly._source.timestamp; + const bucketSpanInSeconds = topAnomaly._source.bucket_span; return { count: aggTypeResults.doc_count, @@ -315,26 +249,32 @@ export function alertingServiceProvider(mlClient: MlClient, datafeedsService: Da alertInstanceKey, jobIds: [...new Set(requestedAnomalies.map((h) => h._source.job_id))], isInterim: requestedAnomalies.some((h) => h._source.is_interim), - timestamp: topAnomaly._source.timestamp, - timestampIso8601: topAnomaly.fields.timestamp_iso8601[0], - timestampEpoch: topAnomaly.fields.timestamp_epoch[0], - score: topAnomaly.fields.score[0], + timestamp, + timestampIso8601: new Date(timestamp).toISOString(), + timestampEpoch: timestamp / 1000, + score: Math.floor(topAnomaly._source[getScoreFields(resultType, useInitialScore)]), bucketRange: { - start: topAnomaly.fields.start[0], - end: topAnomaly.fields.end[0], + start: new Date( + timestamp - bucketSpanInSeconds * 1000 * TIME_RANGE_PADDING + ).toISOString(), + end: new Date(timestamp + bucketSpanInSeconds * 1000 * TIME_RANGE_PADDING).toISOString(), }, topRecords: v.record_results.top_record_hits.hits.hits.map((h) => { return { ...h._source, - score: h.fields.score[0], + score: Math.floor( + h._source[getScoreFields(ANOMALY_RESULT_TYPE.RECORD, useInitialScore)] + ), unique_key: getRecordKey(h._source), }; }) as RecordAnomalyAlertDoc[], topInfluencers: v.influencer_results.top_influencer_hits.hits.hits.map((h) => { return { ...h._source, - score: h.fields.score[0], - unique_key: h.fields.unique_key[0], + score: Math.floor( + h._source[getScoreFields(ANOMALY_RESULT_TYPE.INFLUENCER, useInitialScore)] + ), + unique_key: `${h._source.timestamp}_${h._source.influencer_field_name}_${h._source.influencer_field_value}`, }; }) as InfluencerAnomalyAlertDoc[], }; @@ -447,7 +387,7 @@ export function alertingServiceProvider(mlClient: MlClient, datafeedsService: Da const resultsLabel = getAggResultsLabel(params.resultType); - const formatter = getResultsFormatter(params.resultType); + const formatter = getResultsFormatter(params.resultType, !!previewTimeInterval); return (previewTimeInterval ? (result as { diff --git a/x-pack/plugins/security/common/index.ts b/x-pack/plugins/security/common/index.ts index 8b99ac3c5761b5..034c25758a1f0c 100644 --- a/x-pack/plugins/security/common/index.ts +++ b/x-pack/plugins/security/common/index.ts @@ -6,3 +6,4 @@ */ export { SecurityLicense } from './licensing'; +export { AuthenticatedUser } from './model'; diff --git a/x-pack/plugins/security/server/authentication/authentication_service.mock.ts b/x-pack/plugins/security/server/authentication/authentication_service.mock.ts index ba3297aeb5493e..ba73d3b196d2f8 100644 --- a/x-pack/plugins/security/server/authentication/authentication_service.mock.ts +++ b/x-pack/plugins/security/server/authentication/authentication_service.mock.ts @@ -8,10 +8,10 @@ import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; import { apiKeysMock } from './api_keys/api_keys.mock'; -import type { AuthenticationServiceStart } from './authentication_service'; +import type { AuthenticationServiceStartInternal } from './authentication_service'; export const authenticationServiceMock = { - createStart: (): DeeplyMockedKeys => ({ + createStart: (): DeeplyMockedKeys => ({ apiKeys: apiKeysMock.create(), login: jest.fn(), logout: jest.fn(), diff --git a/x-pack/plugins/security/server/authentication/authentication_service.ts b/x-pack/plugins/security/server/authentication/authentication_service.ts index e5895422e7a743..946fedbeee04ff 100644 --- a/x-pack/plugins/security/server/authentication/authentication_service.ts +++ b/x-pack/plugins/security/server/authentication/authentication_service.ts @@ -51,7 +51,7 @@ interface AuthenticationServiceStartParams { loggers: LoggerFactory; } -export interface AuthenticationServiceStart { +export interface AuthenticationServiceStartInternal extends AuthenticationServiceStart { apiKeys: Pick< APIKeys, | 'areAPIKeysEnabled' @@ -66,6 +66,21 @@ export interface AuthenticationServiceStart { getCurrentUser: (request: KibanaRequest) => AuthenticatedUser | null; } +/** + * Authentication services available on the security plugin's start contract. + */ +export interface AuthenticationServiceStart { + apiKeys: Pick< + APIKeys, + | 'areAPIKeysEnabled' + | 'create' + | 'invalidate' + | 'grantAsInternalUser' + | 'invalidateAsInternalUser' + >; + getCurrentUser: (request: KibanaRequest) => AuthenticatedUser | null; +} + export class AuthenticationService { private license!: SecurityLicense; private authenticator?: Authenticator; @@ -212,7 +227,7 @@ export class AuthenticationService { legacyAuditLogger, loggers, session, - }: AuthenticationServiceStartParams): AuthenticationServiceStart { + }: AuthenticationServiceStartParams): AuthenticationServiceStartInternal { const apiKeys = new APIKeys({ clusterClient, logger: this.logger.get('api-key'), diff --git a/x-pack/plugins/security/server/authentication/index.ts b/x-pack/plugins/security/server/authentication/index.ts index f7f5f82d2858b1..4f82c5653baa9a 100644 --- a/x-pack/plugins/security/server/authentication/index.ts +++ b/x-pack/plugins/security/server/authentication/index.ts @@ -6,7 +6,11 @@ */ export { canRedirectRequest } from './can_redirect_request'; -export { AuthenticationService, AuthenticationServiceStart } from './authentication_service'; +export { + AuthenticationService, + AuthenticationServiceStart, + AuthenticationServiceStartInternal, +} from './authentication_service'; export { AuthenticationResult } from './authentication_result'; export { DeauthenticationResult } from './deauthentication_result'; export { diff --git a/x-pack/plugins/security/server/authorization/authorization_service.tsx b/x-pack/plugins/security/server/authorization/authorization_service.tsx index 1e2588dafe2337..c5adb3aff670e0 100644 --- a/x-pack/plugins/security/server/authorization/authorization_service.tsx +++ b/x-pack/plugins/security/server/authorization/authorization_service.tsx @@ -72,7 +72,7 @@ interface AuthorizationServiceStartParams { online$: Observable; } -export interface AuthorizationServiceSetup { +export interface AuthorizationServiceSetupInternal extends AuthorizationServiceSetup { actions: Actions; checkPrivilegesWithRequest: CheckPrivilegesWithRequest; checkPrivilegesDynamicallyWithRequest: CheckPrivilegesDynamicallyWithRequest; @@ -82,6 +82,21 @@ export interface AuthorizationServiceSetup { privileges: PrivilegesService; } +/** + * Authorization services available on the setup contract of the security plugin. + */ +export interface AuthorizationServiceSetup { + /** + * Actions are used to create the "actions" that are associated with Elasticsearch's + * application privileges, and are used to perform the authorization checks implemented + * by the various `checkPrivilegesWithRequest` derivatives + */ + actions: Actions; + checkPrivilegesWithRequest: CheckPrivilegesWithRequest; + checkPrivilegesDynamicallyWithRequest: CheckPrivilegesDynamicallyWithRequest; + mode: AuthorizationMode; +} + export class AuthorizationService { private logger!: Logger; private applicationName!: string; @@ -101,7 +116,7 @@ export class AuthorizationService { kibanaIndexName, getSpacesService, getCurrentUser, - }: AuthorizationServiceSetupParams): AuthorizationServiceSetup { + }: AuthorizationServiceSetupParams): AuthorizationServiceSetupInternal { this.logger = loggers.get('authorization'); this.applicationName = `${APPLICATION_PREFIX}${kibanaIndexName}`; diff --git a/x-pack/plugins/security/server/authorization/index.ts b/x-pack/plugins/security/server/authorization/index.ts index 16a3c2ae50058c..4d67f3435e7dab 100644 --- a/x-pack/plugins/security/server/authorization/index.ts +++ b/x-pack/plugins/security/server/authorization/index.ts @@ -6,6 +6,10 @@ */ export { Actions } from './actions'; -export { AuthorizationService, AuthorizationServiceSetup } from './authorization_service'; +export { + AuthorizationService, + AuthorizationServiceSetup, + AuthorizationServiceSetupInternal, +} from './authorization_service'; export { CheckSavedObjectsPrivileges } from './check_saved_objects_privileges'; export { CheckPrivilegesPayload } from './types'; diff --git a/x-pack/plugins/security/server/index.ts b/x-pack/plugins/security/server/index.ts index e50ab66a92547e..a48c6833096ccb 100644 --- a/x-pack/plugins/security/server/index.ts +++ b/x-pack/plugins/security/server/index.ts @@ -25,6 +25,7 @@ export type { InvalidateAPIKeysParams, InvalidateAPIKeyResult, GrantAPIKeyResult, + AuthenticationServiceStart, } from './authentication'; export type { CheckPrivilegesPayload } from './authorization'; export type AuthorizationServiceSetup = SecurityPluginStart['authz']; @@ -32,6 +33,7 @@ export { LegacyAuditLogger, AuditLogger, AuditEvent } from './audit'; export type { SecurityPluginSetup, SecurityPluginStart }; export type { AuthenticatedUser } from '../common/model'; export { ROUTE_TAG_CAN_REDIRECT } from './routes/tags'; +export { AuditServiceSetup } from './audit'; export const config: PluginConfigDescriptor> = { schema: ConfigSchema, diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index 57be308525fddd..98f1335b534505 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -10,7 +10,6 @@ import { combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; import type { TypeOf } from '@kbn/config-schema'; -import type { RecursiveReadonly } from '@kbn/utility-types'; import type { CoreSetup, CoreStart, @@ -36,10 +35,14 @@ import type { AnonymousAccessServiceStart } from './anonymous_access'; import { AnonymousAccessService } from './anonymous_access'; import type { AuditServiceSetup } from './audit'; import { AuditService, SecurityAuditLogger } from './audit'; -import type { AuthenticationServiceStart } from './authentication'; +import type { + AuthenticationServiceStart, + AuthenticationServiceStartInternal, +} from './authentication'; import { AuthenticationService } from './authentication'; import type { AuthorizationServiceSetup } from './authorization'; import { AuthorizationService } from './authorization'; +import type { AuthorizationServiceSetupInternal } from './authorization/authorization_service'; import type { ConfigSchema, ConfigType } from './config'; import { createConfig } from './config'; import { ElasticsearchService } from './elasticsearch'; @@ -74,11 +77,14 @@ export interface SecurityPluginSetup { /** * @deprecated Use `authz` methods from the `SecurityServiceStart` contract instead. */ - authz: Pick< - AuthorizationServiceSetup, - 'actions' | 'checkPrivilegesDynamicallyWithRequest' | 'checkPrivilegesWithRequest' | 'mode' - >; + authz: AuthorizationServiceSetup; + /** + * Exposes information about the available security features under the current license. + */ license: SecurityLicense; + /** + * Exposes services for audit logging. + */ audit: AuditServiceSetup; } @@ -86,11 +92,14 @@ export interface SecurityPluginSetup { * Describes public Security plugin contract returned at the `start` stage. */ export interface SecurityPluginStart { - authc: Pick; - authz: Pick< - AuthorizationServiceSetup, - 'actions' | 'checkPrivilegesDynamicallyWithRequest' | 'checkPrivilegesWithRequest' | 'mode' - >; + /** + * Authentication services to confirm the user is who they say they are. + */ + authc: AuthenticationServiceStart; + /** + * Authorization services to manage and access the permissions a particular user has. + */ + authz: AuthorizationServiceSetup; } export interface PluginSetupDependencies { @@ -113,14 +122,9 @@ export interface PluginStartDependencies { * Represents Security Plugin instance that will be managed by the Kibana plugin system. */ export class SecurityPlugin - implements - Plugin< - RecursiveReadonly, - RecursiveReadonly, - PluginSetupDependencies - > { + implements Plugin { private readonly logger: Logger; - private authorizationSetup?: AuthorizationServiceSetup; + private authorizationSetup?: AuthorizationServiceSetupInternal; private auditSetup?: AuditServiceSetup; private anonymousAccessStart?: AnonymousAccessServiceStart; private configSubscription?: Subscription; @@ -152,7 +156,7 @@ export class SecurityPlugin private readonly authenticationService = new AuthenticationService( this.initializerContext.logger.get('authentication') ); - private authenticationStart?: AuthenticationServiceStart; + private authenticationStart?: AuthenticationServiceStartInternal; private readonly getAuthentication = () => { if (!this.authenticationStart) { throw new Error(`authenticationStart is not registered!`); diff --git a/x-pack/plugins/security/server/routes/api_keys/create.test.ts b/x-pack/plugins/security/server/routes/api_keys/create.test.ts index 502a7cb1246c49..ee28681adbd5f2 100644 --- a/x-pack/plugins/security/server/routes/api_keys/create.test.ts +++ b/x-pack/plugins/security/server/routes/api_keys/create.test.ts @@ -12,7 +12,7 @@ import type { RequestHandler } from 'src/core/server'; import { kibanaResponseFactory } from 'src/core/server'; import { httpServerMock } from 'src/core/server/mocks'; -import type { AuthenticationServiceStart } from '../../authentication'; +import type { AuthenticationServiceStartInternal } from '../../authentication'; import { authenticationServiceMock } from '../../authentication/authentication_service.mock'; import type { SecurityRequestHandlerContext } from '../../types'; import { routeDefinitionParamsMock } from '../index.mock'; @@ -28,7 +28,7 @@ describe('Create API Key route', () => { } let routeHandler: RequestHandler; - let authc: DeeplyMockedKeys; + let authc: DeeplyMockedKeys; beforeEach(() => { authc = authenticationServiceMock.createStart(); const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); diff --git a/x-pack/plugins/security/server/routes/api_keys/enabled.test.ts b/x-pack/plugins/security/server/routes/api_keys/enabled.test.ts index da097faf8c6b27..1000e79563b571 100644 --- a/x-pack/plugins/security/server/routes/api_keys/enabled.test.ts +++ b/x-pack/plugins/security/server/routes/api_keys/enabled.test.ts @@ -12,7 +12,7 @@ import type { RequestHandler } from 'src/core/server'; import { kibanaResponseFactory } from 'src/core/server'; import { httpServerMock } from 'src/core/server/mocks'; -import type { AuthenticationServiceStart } from '../../authentication'; +import type { AuthenticationServiceStartInternal } from '../../authentication'; import { authenticationServiceMock } from '../../authentication/authentication_service.mock'; import type { SecurityRequestHandlerContext } from '../../types'; import { routeDefinitionParamsMock } from '../index.mock'; @@ -28,7 +28,7 @@ describe('API keys enabled', () => { } let routeHandler: RequestHandler; - let authc: DeeplyMockedKeys; + let authc: DeeplyMockedKeys; beforeEach(() => { authc = authenticationServiceMock.createStart(); const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); diff --git a/x-pack/plugins/security/server/routes/authentication/common.test.ts b/x-pack/plugins/security/server/routes/authentication/common.test.ts index 1e0b6784a45c82..5acc5817bfb3e9 100644 --- a/x-pack/plugins/security/server/routes/authentication/common.test.ts +++ b/x-pack/plugins/security/server/routes/authentication/common.test.ts @@ -13,7 +13,7 @@ import { httpServerMock } from 'src/core/server/mocks'; import type { SecurityLicense, SecurityLicenseFeatures } from '../../../common/licensing'; import { mockAuthenticatedUser } from '../../../common/model/authenticated_user.mock'; -import type { AuthenticationServiceStart } from '../../authentication'; +import type { AuthenticationServiceStartInternal } from '../../authentication'; import { AuthenticationResult, DeauthenticationResult, @@ -28,7 +28,7 @@ import { defineCommonRoutes } from './common'; describe('Common authentication routes', () => { let router: jest.Mocked; - let authc: DeeplyMockedKeys; + let authc: DeeplyMockedKeys; let license: jest.Mocked; let mockContext: SecurityRequestHandlerContext; beforeEach(() => { diff --git a/x-pack/plugins/security/server/routes/authentication/saml.test.ts b/x-pack/plugins/security/server/routes/authentication/saml.test.ts index 3b2497ed9f30ba..c28c435217ef3a 100644 --- a/x-pack/plugins/security/server/routes/authentication/saml.test.ts +++ b/x-pack/plugins/security/server/routes/authentication/saml.test.ts @@ -11,7 +11,7 @@ import type { RequestHandler, RouteConfig } from 'src/core/server'; import { httpServerMock } from 'src/core/server/mocks'; import { mockAuthenticatedUser } from '../../../common/model/authenticated_user.mock'; -import type { AuthenticationServiceStart } from '../../authentication'; +import type { AuthenticationServiceStartInternal } from '../../authentication'; import { AuthenticationResult, SAMLLogin } from '../../authentication'; import { authenticationServiceMock } from '../../authentication/authentication_service.mock'; import type { SecurityRouter } from '../../types'; @@ -21,7 +21,7 @@ import { defineSAMLRoutes } from './saml'; describe('SAML authentication routes', () => { let router: jest.Mocked; - let authc: DeeplyMockedKeys; + let authc: DeeplyMockedKeys; beforeEach(() => { const routeParamsMock = routeDefinitionParamsMock.create(); router = routeParamsMock.router; diff --git a/x-pack/plugins/security/server/routes/index.ts b/x-pack/plugins/security/server/routes/index.ts index cdb3a2fa289fdd..e36ca1b9ab72e5 100644 --- a/x-pack/plugins/security/server/routes/index.ts +++ b/x-pack/plugins/security/server/routes/index.ts @@ -10,8 +10,8 @@ import type { HttpResources, IBasePath, Logger } from 'src/core/server'; import type { KibanaFeature } from '../../../features/server'; import type { SecurityLicense } from '../../common/licensing'; -import type { AuthenticationServiceStart } from '../authentication'; -import type { AuthorizationServiceSetup } from '../authorization'; +import type { AuthenticationServiceStartInternal } from '../authentication'; +import type { AuthorizationServiceSetupInternal } from '../authorization'; import type { ConfigType } from '../config'; import type { SecurityFeatureUsageServiceStart } from '../feature_usage'; import type { Session } from '../session_management'; @@ -34,12 +34,12 @@ export interface RouteDefinitionParams { httpResources: HttpResources; logger: Logger; config: ConfigType; - authz: AuthorizationServiceSetup; + authz: AuthorizationServiceSetupInternal; getSession: () => PublicMethodsOf; license: SecurityLicense; getFeatures: () => Promise; getFeatureUsageService: () => SecurityFeatureUsageServiceStart; - getAuthenticationService: () => AuthenticationServiceStart; + getAuthenticationService: () => AuthenticationServiceStartInternal; } export function defineRoutes(params: RouteDefinitionParams) { diff --git a/x-pack/plugins/security/server/routes/users/change_password.test.ts b/x-pack/plugins/security/server/routes/users/change_password.test.ts index a97fce7ea4b190..e5f4381a204212 100644 --- a/x-pack/plugins/security/server/routes/users/change_password.test.ts +++ b/x-pack/plugins/security/server/routes/users/change_password.test.ts @@ -15,8 +15,8 @@ import { kibanaResponseFactory } from 'src/core/server'; import { coreMock, httpServerMock } from 'src/core/server/mocks'; import { mockAuthenticatedUser } from '../../../common/model/authenticated_user.mock'; -import type { AuthenticationServiceStart } from '../../authentication'; import { AuthenticationResult } from '../../authentication'; +import type { AuthenticationServiceStartInternal } from '../../authentication/authentication_service'; import { authenticationServiceMock } from '../../authentication/authentication_service.mock'; import type { Session } from '../../session_management'; import { sessionMock } from '../../session_management/session.mock'; @@ -26,7 +26,7 @@ import { defineChangeUserPasswordRoutes } from './change_password'; describe('Change password', () => { let router: jest.Mocked; - let authc: DeeplyMockedKeys; + let authc: DeeplyMockedKeys; let session: jest.Mocked>; let routeHandler: RequestHandler; let routeConfig: RouteConfig; diff --git a/x-pack/plugins/security/server/saved_objects/index.ts b/x-pack/plugins/security/server/saved_objects/index.ts index e052fd1c7ab6a4..837b3c594d3968 100644 --- a/x-pack/plugins/security/server/saved_objects/index.ts +++ b/x-pack/plugins/security/server/saved_objects/index.ts @@ -9,7 +9,7 @@ import type { CoreSetup, LegacyRequest } from 'src/core/server'; import { KibanaRequest, SavedObjectsClient } from '../../../../../src/core/server'; import type { AuditServiceSetup, SecurityAuditLogger } from '../audit'; -import type { AuthorizationServiceSetup } from '../authorization'; +import type { AuthorizationServiceSetupInternal } from '../authorization/authorization_service'; import type { SpacesService } from '../plugin'; import { SecureSavedObjectsClientWrapper } from './secure_saved_objects_client_wrapper'; @@ -17,7 +17,7 @@ interface SetupSavedObjectsParams { legacyAuditLogger: SecurityAuditLogger; audit: AuditServiceSetup; authz: Pick< - AuthorizationServiceSetup, + AuthorizationServiceSetupInternal, 'mode' | 'actions' | 'checkSavedObjectsPrivilegesWithRequest' >; savedObjects: CoreSetup['savedObjects']; diff --git a/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.test.ts b/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.test.ts index 0b8a7abab23828..bc7cb727edd805 100644 --- a/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.test.ts +++ b/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.test.ts @@ -15,7 +15,10 @@ import { spacesClientMock } from '../../../spaces/server/mocks'; import type { AuditEvent, AuditLogger } from '../audit'; import { SpaceAuditAction } from '../audit'; import { auditServiceMock } from '../audit/index.mock'; -import type { AuthorizationServiceSetup } from '../authorization'; +import type { + AuthorizationServiceSetup, + AuthorizationServiceSetupInternal, +} from '../authorization'; import { authorizationMock } from '../authorization/index.mock'; import type { CheckPrivilegesResponse } from '../authorization/types'; import type { LegacySpacesAuditLogger } from './legacy_audit_logger'; @@ -85,7 +88,9 @@ const setup = ({ securityEnabled = false }: Opts = {}) => { }; }; -const expectNoAuthorizationCheck = (authorization: jest.Mocked) => { +const expectNoAuthorizationCheck = ( + authorization: jest.Mocked +) => { expect(authorization.checkPrivilegesDynamicallyWithRequest).not.toHaveBeenCalled(); expect(authorization.checkPrivilegesWithRequest).not.toHaveBeenCalled(); expect(authorization.checkSavedObjectsPrivilegesWithRequest).not.toHaveBeenCalled(); diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 91b48afdc4ed1e..87e99a4b472e7c 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -186,6 +186,7 @@ export const DETECTION_ENGINE_INDEX_URL = `${DETECTION_ENGINE_URL}/index`; export const DETECTION_ENGINE_TAGS_URL = `${DETECTION_ENGINE_URL}/tags`; export const DETECTION_ENGINE_RULES_STATUS_URL = `${DETECTION_ENGINE_RULES_URL}/_find_statuses`; export const DETECTION_ENGINE_PREPACKAGED_RULES_STATUS_URL = `${DETECTION_ENGINE_RULES_URL}/prepackaged/_status`; +export const DETECTION_ENGINE_RULES_BULK_ACTION = `${DETECTION_ENGINE_RULES_URL}/_bulk_action`; export const TIMELINE_URL = '/api/timeline'; export const TIMELINES_URL = '/api/timelines'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts index 7b49b68ab79a1d..c9a9d3bdcb24c1 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts @@ -82,6 +82,8 @@ export const ruleIdOrUndefined = t.union([rule_id, t.undefined]); export type RuleIdOrUndefined = t.TypeOf; export const id = UUID; +export type Id = t.TypeOf; + export const idOrUndefined = t.union([id, t.undefined]); export type IdOrUndefined = t.TypeOf; @@ -408,3 +410,13 @@ export const privilege = t.type({ }); export type Privilege = t.TypeOf; + +export enum BulkAction { + 'enable' = 'enable', + 'disable' = 'disable', + 'export' = 'export', + 'delete' = 'delete', + 'duplicate' = 'duplicate', +} + +export const bulkAction = t.keyof(BulkAction); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts index 1035e9128305c2..7722feb5f080d7 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts @@ -17,3 +17,4 @@ export * from './query_signals_index_schema'; export * from './set_signal_status_schema'; export * from './update_rules_bulk_schema'; export * from './rule_schemas'; +export * from './perform_bulk_action_schema'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.mock.ts new file mode 100644 index 00000000000000..cb78168fbec6e2 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.mock.ts @@ -0,0 +1,14 @@ +/* + * 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 { BulkAction } from '../common/schemas'; +import { PerformBulkActionSchema } from './perform_bulk_action_schema'; + +export const getPerformBulkActionSchemaMock = (): PerformBulkActionSchema => ({ + query: '', + action: BulkAction.disable, +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.test.ts new file mode 100644 index 00000000000000..a9707b88f52406 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.test.ts @@ -0,0 +1,68 @@ +/* + * 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 { performBulkActionSchema, PerformBulkActionSchema } from './perform_bulk_action_schema'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; +import { left } from 'fp-ts/lib/Either'; +import { BulkAction } from '../common/schemas'; + +describe('perform_bulk_action_schema', () => { + test('query and action is valid', () => { + const payload: PerformBulkActionSchema = { + query: 'name: test', + action: BulkAction.enable, + }; + + const decoded = performBulkActionSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = foldLeftRight(checked); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('missing query is valid', () => { + const payload: PerformBulkActionSchema = { + query: undefined, + action: BulkAction.enable, + }; + + const decoded = performBulkActionSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = foldLeftRight(checked); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('missing action is invalid', () => { + const payload: Omit = { + query: 'name: test', + }; + + const decoded = performBulkActionSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = foldLeftRight(checked); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "action"', + ]); + expect(message.schema).toEqual({}); + }); + + test('unknown action is invalid', () => { + const payload: Omit & { action: 'unknown' } = { + query: 'name: test', + action: 'unknown', + }; + + const decoded = performBulkActionSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = foldLeftRight(checked); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "unknown" supplied to "action"', + ]); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.ts new file mode 100644 index 00000000000000..adb26f107c8cd1 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.ts @@ -0,0 +1,18 @@ +/* + * 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 * as t from 'io-ts'; +import { bulkAction, queryOrUndefined } from '../common/schemas'; + +export const performBulkActionSchema = t.exact( + t.type({ + query: queryOrUndefined, + action: bulkAction, + }) +); + +export type PerformBulkActionSchema = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/endpoint/types/index.ts b/x-pack/plugins/security_solution/common/endpoint/types/index.ts index e006944eb914fe..1e0d798cf7f07d 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/index.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/index.ts @@ -1114,3 +1114,15 @@ export interface GetExceptionSummaryResponse { macos: number; linux: number; } + +/** + * Supported React-Router state for the Generic List page + */ +export interface ListPageRouteState { + /** Where the user should be redirected to when the `Back` button is clicked */ + onBackButtonNavigateTo: Parameters; + /** The URL for the `Back` button */ + backButtonUrl?: string; + /** The label for the button */ + backButtonLabel?: string; +} diff --git a/x-pack/plugins/security_solution/common/endpoint/types/trusted_apps.ts b/x-pack/plugins/security_solution/common/endpoint/types/trusted_apps.ts index 8d66370fea4d36..94a2e7f236bebd 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/trusted_apps.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/trusted_apps.ts @@ -6,7 +6,6 @@ */ import { TypeOf } from '@kbn/config-schema'; -import { ApplicationStart } from 'kibana/public'; import { DeleteTrustedAppsRequestSchema, @@ -133,15 +132,3 @@ export type TrustedApp = NewTrustedApp & { updated_at: string; updated_by: string; }; - -/** - * Supported React-Router state for the Trusted Apps List page - */ -export interface TrustedAppsListPageRouteState { - /** Where the user should be redirected to when the `Back` button is clicked */ - onBackButtonNavigateTo: Parameters; - /** The URL for the `Back` button */ - backButtonUrl?: string; - /** The label for the button */ - backButtonLabel?: string; -} diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/custom_query_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/custom_query_rule.spec.ts index 2f98cb15287d63..8210c7c6d8b20b 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/custom_query_rule.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/custom_query_rule.spec.ts @@ -80,7 +80,7 @@ import { waitForAlertsPanelToBeLoaded, } from '../../tasks/alerts'; import { - changeRowsPerPageTo300, + changeRowsPerPageTo100, deleteFirstRule, deleteSelectedRules, editFirstRule, @@ -159,7 +159,7 @@ describe('Custom detection rules creation', () => { cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); cy.get(RULES_TABLE).then(($table) => { cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRules); diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/event_correlation_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/event_correlation_rule.spec.ts index 0dbecde3d4d3f6..b38796cca373d3 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/event_correlation_rule.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/event_correlation_rule.spec.ts @@ -56,7 +56,7 @@ import { waitForAlertsPanelToBeLoaded, } from '../../tasks/alerts'; import { - changeRowsPerPageTo300, + changeRowsPerPageTo100, filterByCustomRules, goToCreateNewRule, goToRuleDetails, @@ -113,7 +113,7 @@ describe('Detection rules, EQL', () => { cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); cy.get(RULES_TABLE).then(($table) => { cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRules); @@ -208,7 +208,7 @@ describe('Detection rules, sequence EQL', () => { cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); cy.get(RULES_TABLE).then(($table) => { cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRules); diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/indicator_match_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/indicator_match_rule.spec.ts index d0f2cd9f45743f..bc8cf0137fa830 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/indicator_match_rule.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/indicator_match_rule.spec.ts @@ -78,7 +78,7 @@ import { scrollJsonViewToBottom, } from '../../tasks/alerts_details'; import { - changeRowsPerPageTo300, + changeRowsPerPageTo100, duplicateFirstRule, duplicateSelectedRules, duplicateRuleFromMenu, @@ -424,7 +424,7 @@ describe('indicator match', () => { cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); cy.get(RULES_TABLE).then(($table) => { cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRules); diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/machine_learning_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/machine_learning_rule.spec.ts index 0fe1326947a120..65dde40bbd76b8 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/machine_learning_rule.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/machine_learning_rule.spec.ts @@ -46,7 +46,7 @@ import { waitForAlertsPanelToBeLoaded, } from '../../tasks/alerts'; import { - changeRowsPerPageTo300, + changeRowsPerPageTo100, filterByCustomRules, goToCreateNewRule, goToRuleDetails, @@ -90,7 +90,7 @@ describe('Detection rules, machine learning', () => { cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); cy.get(RULES_TABLE).then(($table) => { cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRules); diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/override.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/override.spec.ts index eb10f32bb89897..f9f1ca14c81642 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/override.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/override.spec.ts @@ -68,7 +68,7 @@ import { waitForAlertsPanelToBeLoaded, } from '../../tasks/alerts'; import { - changeRowsPerPageTo300, + changeRowsPerPageTo100, filterByCustomRules, goToCreateNewRule, goToRuleDetails, @@ -121,7 +121,7 @@ describe('Detection rules, override', () => { cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); const expectedNumberOfRules = 1; cy.get(RULES_TABLE).then(($table) => { diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/prebuilt_rules.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/prebuilt_rules.spec.ts index fb0a01bd1c7d30..74e1d082ae4103 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/prebuilt_rules.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/prebuilt_rules.spec.ts @@ -8,23 +8,29 @@ import { COLLAPSED_ACTION_BTN, ELASTIC_RULES_BTN, + pageSelector, RELOAD_PREBUILT_RULES_BTN, - RULES_ROW, - RULES_TABLE, + RULES_EMPTY_PROMPT, + RULE_SWITCH, SHOWING_RULES_TEXT, } from '../../screens/alerts_detection_rules'; import { goToManageAlertsDetectionRules, waitForAlertsIndexToBeCreated } from '../../tasks/alerts'; import { - changeRowsPerPageTo300, + changeRowsPerPageTo100, deleteFirstRule, deleteSelectedRules, loadPrebuiltDetectionRules, - goToNextPage, reloadDeletedRules, selectNumberOfRules, waitForRulesTableToBeLoaded, waitForPrebuiltDetectionRulesToBeLoaded, + selectAllRules, + confirmRulesDelete, + activateSelectedRules, + waitForRuleToChangeStatus, + deactivateSelectedRules, + changeRowsPerPageTo, } from '../../tasks/alerts_detection_rules'; import { loginAndWaitForPageWithoutDateRange } from '../../tasks/login'; @@ -39,7 +45,9 @@ describe('Alerts rules, prebuilt rules', () => { }); it('Loads prebuilt rules', () => { + const rowsPerPage = 100; const expectedNumberOfRules = totalNumberOfPrebuiltRules; + const expectedNumberOfPages = Math.ceil(totalNumberOfPrebuiltRules / rowsPerPage); const expectedElasticRulesBtnText = `Elastic rules (${expectedNumberOfRules})`; loginAndWaitForPageWithoutDateRange(DETECTIONS_URL); @@ -51,23 +59,14 @@ describe('Alerts rules, prebuilt rules', () => { cy.get(ELASTIC_RULES_BTN).should('have.text', expectedElasticRulesBtnText); - changeRowsPerPageTo300(); + changeRowsPerPageTo(rowsPerPage); cy.get(SHOWING_RULES_TEXT).should('have.text', `Showing ${expectedNumberOfRules} rules`); - cy.get(RULES_TABLE).then(($table1) => { - const firstScreenRules = $table1.find(RULES_ROW).length; - goToNextPage(); - cy.get(RULES_TABLE).then(($table2) => { - const secondScreenRules = $table2.find(RULES_ROW).length; - const totalNumberOfRules = firstScreenRules + secondScreenRules; - - expect(totalNumberOfRules).to.eql(expectedNumberOfRules); - }); - }); + cy.get(pageSelector(expectedNumberOfPages)).should('exist'); }); }); -describe('Deleting prebuilt rules', () => { +describe('Actions with prebuilt rules', () => { beforeEach(() => { const expectedNumberOfRules = totalNumberOfPrebuiltRules; const expectedElasticRulesBtnText = `Elastic rules (${expectedNumberOfRules})`; @@ -81,11 +80,30 @@ describe('Deleting prebuilt rules', () => { waitForPrebuiltDetectionRulesToBeLoaded(); cy.get(ELASTIC_RULES_BTN).should('have.text', expectedElasticRulesBtnText); + }); + + it('Allows to activate/deactivate all rules at once', () => { + selectAllRules(); + activateSelectedRules(); + waitForRuleToChangeStatus(); + cy.get(RULE_SWITCH).should('have.attr', 'aria-checked', 'true'); - changeRowsPerPageTo300(); + selectAllRules(); + deactivateSelectedRules(); + waitForRuleToChangeStatus(); + cy.get(RULE_SWITCH).should('have.attr', 'aria-checked', 'false'); + }); + + it('Allows to delete all rules at once', () => { + selectAllRules(); + deleteSelectedRules(); + confirmRulesDelete(); + cy.get(RULES_EMPTY_PROMPT).should('be.visible'); }); it('Does not allow to delete one rule when more than one is selected', () => { + changeRowsPerPageTo100(); + const numberOfRulesToBeSelected = 2; selectNumberOfRules(numberOfRulesToBeSelected); @@ -95,12 +113,14 @@ describe('Deleting prebuilt rules', () => { }); it('Deletes and recovers one rule', () => { + changeRowsPerPageTo100(); + const expectedNumberOfRulesAfterDeletion = totalNumberOfPrebuiltRules - 1; const expectedNumberOfRulesAfterRecovering = totalNumberOfPrebuiltRules; deleteFirstRule(); cy.reload(); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); cy.get(ELASTIC_RULES_BTN).should( 'have.text', @@ -114,7 +134,7 @@ describe('Deleting prebuilt rules', () => { cy.get(RELOAD_PREBUILT_RULES_BTN).should('not.exist'); cy.reload(); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); cy.get(ELASTIC_RULES_BTN).should( 'have.text', @@ -123,6 +143,8 @@ describe('Deleting prebuilt rules', () => { }); it('Deletes and recovers more than one rule', () => { + changeRowsPerPageTo100(); + const numberOfRulesToBeSelected = 2; const expectedNumberOfRulesAfterDeletion = totalNumberOfPrebuiltRules - 2; const expectedNumberOfRulesAfterRecovering = totalNumberOfPrebuiltRules; @@ -130,7 +152,7 @@ describe('Deleting prebuilt rules', () => { selectNumberOfRules(numberOfRulesToBeSelected); deleteSelectedRules(); cy.reload(); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); cy.get(RELOAD_PREBUILT_RULES_BTN).should('exist'); cy.get(RELOAD_PREBUILT_RULES_BTN).should( @@ -147,7 +169,7 @@ describe('Deleting prebuilt rules', () => { cy.get(RELOAD_PREBUILT_RULES_BTN).should('not.exist'); cy.reload(); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); cy.get(ELASTIC_RULES_BTN).should( 'have.text', diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts index 0cf3caa09814c2..f1ee0d39f545f5 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts @@ -31,7 +31,7 @@ import { resetAllRulesIdleModalTimeout, sortByActivatedRules, waitForRulesTableToBeLoaded, - waitForRuleToBeActivated, + waitForRuleToChangeStatus, } from '../../tasks/alerts_detection_rules'; import { loginAndWaitForPageWithoutDateRange } from '../../tasks/login'; import { DEFAULT_RULE_REFRESH_INTERVAL_VALUE } from '../../../common/constants'; @@ -62,13 +62,13 @@ describe('Alerts detection rules', () => { .invoke('text') .then((secondInitialRuleName) => { activateRule(SECOND_RULE); - waitForRuleToBeActivated(); + waitForRuleToChangeStatus(); cy.get(RULE_NAME) .eq(FOURTH_RULE) .invoke('text') .then((fourthInitialRuleName) => { activateRule(FOURTH_RULE); - waitForRuleToBeActivated(); + waitForRuleToChangeStatus(); sortByActivatedRules(); cy.get(RULE_NAME) .eq(FIRST_RULE) diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/threshold_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/threshold_rule.spec.ts index 7c09b311807beb..0f4095372f92a7 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/threshold_rule.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/threshold_rule.spec.ts @@ -59,7 +59,7 @@ import { waitForAlertsPanelToBeLoaded, } from '../../tasks/alerts'; import { - changeRowsPerPageTo300, + changeRowsPerPageTo100, filterByCustomRules, goToCreateNewRule, goToRuleDetails, @@ -113,7 +113,7 @@ describe('Detection rules, threshold', () => { cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); - changeRowsPerPageTo300(); + changeRowsPerPageTo100(); const expectedNumberOfRules = 1; cy.get(RULES_TABLE).then(($table) => { diff --git a/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts b/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts index 70dde344c88b6c..ba071184d98eba 100644 --- a/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts +++ b/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts @@ -25,6 +25,12 @@ export const DUPLICATE_RULE_MENU_PANEL_BTN = '[data-test-subj="rules-details-dup export const REFRESH_BTN = '[data-test-subj="refreshRulesAction"] button'; +export const ACTIVATE_RULE_BULK_BTN = '[data-test-subj="activateRuleBulk"]'; + +export const DEACTIVATE_RULE_BULK_BTN = '[data-test-subj="deactivateRuleBulk"]'; + +export const EXPORT_RULE_BULK_BTN = '[data-test-subj="exportRuleBulk"]'; + export const DELETE_RULE_BULK_BTN = '[data-test-subj="deleteRuleBulk"]'; export const DUPLICATE_RULE_BULK_BTN = '[data-test-subj="duplicateRuleBulk"]'; @@ -87,3 +93,11 @@ export const pageSelector = (pageNumber: number) => `[data-test-subj="pagination-button-${pageNumber - 1}"]`; export const NEXT_BTN = '[data-test-subj="pagination-button-next"]'; + +export const SELECT_ALL_RULES_BTN = '[data-test-subj="selectAllRules"]'; + +export const RULES_EMPTY_PROMPT = '[data-test-subj="rulesEmptyPrompt"]'; + +export const RULES_DELETE_CONFIRMATION_MODAL = '[data-test-subj="allRulesDeleteConfirmationModal"]'; + +export const MODAL_CONFIRMATION_BTN = '[data-test-subj="confirmModalConfirmButton"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts index cc14c54a4d84e3..78298c98810772 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts @@ -36,6 +36,12 @@ import { DUPLICATE_RULE_MENU_PANEL_BTN, DUPLICATE_RULE_BULK_BTN, RULES_ROW, + SELECT_ALL_RULES_BTN, + MODAL_CONFIRMATION_BTN, + RULES_DELETE_CONFIRMATION_MODAL, + ACTIVATE_RULE_BULK_BTN, + DEACTIVATE_RULE_BULK_BTN, + EXPORT_RULE_BULK_BTN, } from '../screens/alerts_detection_rules'; import { ALL_ACTIONS, DELETE_RULE } from '../screens/rule_details'; @@ -57,11 +63,6 @@ export const duplicateFirstRule = () => { cy.get(DUPLICATE_RULE_ACTION_BTN).click(); }; -export const duplicateSelectedRules = () => { - cy.get(BULK_ACTIONS_BTN).click({ force: true }); - cy.get(DUPLICATE_RULE_BULK_BTN).click(); -}; - /** * Duplicates the rule from the menu and does additional * pipes and checking that the elements are present on the @@ -106,6 +107,26 @@ export const deleteSelectedRules = () => { cy.get(DELETE_RULE_BULK_BTN).click(); }; +export const duplicateSelectedRules = () => { + cy.get(BULK_ACTIONS_BTN).click({ force: true }); + cy.get(DUPLICATE_RULE_BULK_BTN).click(); +}; + +export const activateSelectedRules = () => { + cy.get(BULK_ACTIONS_BTN).click({ force: true }); + cy.get(ACTIVATE_RULE_BULK_BTN).click(); +}; + +export const deactivateSelectedRules = () => { + cy.get(BULK_ACTIONS_BTN).click({ force: true }); + cy.get(DEACTIVATE_RULE_BULK_BTN).click(); +}; + +export const exportSelectedRules = () => { + cy.get(BULK_ACTIONS_BTN).click({ force: true }); + cy.get(EXPORT_RULE_BULK_BTN).click(); +}; + export const exportFirstRule = () => { cy.get(COLLAPSED_ACTION_BTN).first().click({ force: true }); cy.get(EXPORT_ACTION_BTN).click(); @@ -149,6 +170,17 @@ export const selectNumberOfRules = (numberOfRules: number) => { } }; +export const selectAllRules = () => { + cy.get(SELECT_ALL_RULES_BTN).contains('Select all').click(); + cy.get(SELECT_ALL_RULES_BTN).contains('Clear'); +}; + +export const confirmRulesDelete = () => { + cy.get(RULES_DELETE_CONFIRMATION_MODAL).should('be.visible'); + cy.get(MODAL_CONFIRMATION_BTN).click(); + cy.get(RULES_DELETE_CONFIRMATION_MODAL).should('not.exist'); +}; + export const sortByActivatedRules = () => { cy.get(SORT_RULES_BTN).contains('Activated').click({ force: true }); waitForRulesTableToBeRefreshed(); @@ -174,9 +206,10 @@ export const waitForRulesTableToBeAutoRefreshed = () => { export const waitForPrebuiltDetectionRulesToBeLoaded = () => { cy.get(LOAD_PREBUILT_RULES_BTN).should('not.exist'); cy.get(RULES_TABLE).should('exist'); + cy.get(RULES_TABLE_REFRESH_INDICATOR).should('not.exist'); }; -export const waitForRuleToBeActivated = () => { +export const waitForRuleToChangeStatus = () => { cy.get(RULE_SWITCH_LOADER).should('exist'); cy.get(RULE_SWITCH_LOADER).should('not.exist'); }; @@ -215,8 +248,8 @@ export const changeRowsPerPageTo = (rowsCount: number) => { waitForRulesTableToBeRefreshed(); }; -export const changeRowsPerPageTo300 = () => { - changeRowsPerPageTo(300); +export const changeRowsPerPageTo100 = () => { + changeRowsPerPageTo(100); }; export const goToPage = (pageNumber: number) => { diff --git a/x-pack/plugins/security_solution/public/common/components/generic_downloader/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/generic_downloader/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 219be8cbda311f..00000000000000 --- a/x-pack/plugins/security_solution/public/common/components/generic_downloader/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`GenericDownloader renders correctly against snapshot 1`] = ``; diff --git a/x-pack/plugins/security_solution/public/common/components/generic_downloader/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/generic_downloader/index.test.tsx deleted file mode 100644 index b8066c836de722..00000000000000 --- a/x-pack/plugins/security_solution/public/common/components/generic_downloader/index.test.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 { shallow, mount } from 'enzyme'; -import React from 'react'; -import { GenericDownloaderComponent, ExportSelectedData } from './index'; -import { errorToToaster } from '../toasters'; - -jest.mock('../toasters', () => ({ - useStateToaster: jest.fn(() => [jest.fn(), jest.fn()]), - errorToToaster: jest.fn(), -})); - -describe('GenericDownloader', () => { - test('renders correctly against snapshot', () => { - const wrapper = shallow( - - ); - expect(wrapper).toMatchSnapshot(); - }); - - test('show toaster with correct error message if error occurrs', () => { - mount( - - ); - expect((errorToToaster as jest.Mock).mock.calls[0][0].title).toEqual('Failed to export data…'); - }); -}); diff --git a/x-pack/plugins/security_solution/public/common/components/generic_downloader/index.tsx b/x-pack/plugins/security_solution/public/common/components/generic_downloader/index.tsx deleted file mode 100644 index 2a2e425702755e..00000000000000 --- a/x-pack/plugins/security_solution/public/common/components/generic_downloader/index.tsx +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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 React, { useEffect, useRef } from 'react'; -import styled from 'styled-components'; -import { isFunction } from 'lodash/fp'; -import * as i18n from './translations'; - -import { ExportDocumentsProps } from '../../../detections/containers/detection_engine/rules'; -import { useStateToaster, errorToToaster } from '../toasters'; -import { TimelineErrorResponse } from '../../../../common/types/timeline'; - -const InvisibleAnchor = styled.a` - display: none; -`; - -export type ExportSelectedData = ({ - excludeExportDetails, - filename, - ids, - signal, -}: ExportDocumentsProps) => Promise; - -export interface GenericDownloaderProps { - filename: string; - ids?: string[]; - exportSelectedData: ExportSelectedData; - onExportSuccess?: (exportCount: number) => void; - onExportFailure?: () => void; -} - -/** - * Component for downloading Rules as an exported .ndjson file. Download will occur on each update to `rules` param - * - * @param filename of file to be downloaded - * @param payload Rule[] - * - */ - -export const GenericDownloaderComponent = ({ - exportSelectedData, - filename, - ids, - onExportSuccess, - onExportFailure, -}: GenericDownloaderProps) => { - const anchorRef = useRef(null); - const [, dispatchToaster] = useStateToaster(); - - useEffect(() => { - let isSubscribed = true; - const abortCtrl = new AbortController(); - - const exportData = async () => { - if (anchorRef && anchorRef.current && ids != null && ids.length > 0) { - try { - const exportResponse = await exportSelectedData({ - ids, - signal: abortCtrl.signal, - }); - - if (isSubscribed) { - // this is for supporting IE - if (isFunction(window.navigator.msSaveOrOpenBlob)) { - window.navigator.msSaveBlob(exportResponse); - } else { - const objectURL = window.URL.createObjectURL(exportResponse); - // These are safe-assignments as writes to anchorRef are isolated to exportData - anchorRef.current.href = objectURL; // eslint-disable-line require-atomic-updates - anchorRef.current.download = filename; // eslint-disable-line require-atomic-updates - anchorRef.current.click(); - - if (typeof window.URL.revokeObjectURL === 'function') { - window.URL.revokeObjectURL(objectURL); - } - } - if (onExportSuccess != null) { - onExportSuccess(ids.length); - } - } - } catch (error) { - if (isSubscribed) { - if (onExportFailure != null) { - onExportFailure(); - } - errorToToaster({ title: i18n.EXPORT_FAILURE, error, dispatchToaster }); - } - } - } - }; - - exportData(); - - return () => { - isSubscribed = false; - abortCtrl.abort(); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ids]); - - return ; -}; - -GenericDownloaderComponent.displayName = 'GenericDownloaderComponent'; - -export const GenericDownloader = React.memo(GenericDownloaderComponent); - -GenericDownloader.displayName = 'GenericDownloader'; diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_bool_state.ts b/x-pack/plugins/security_solution/public/common/hooks/use_bool_state.ts new file mode 100644 index 00000000000000..f9204de38d6808 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/hooks/use_bool_state.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback, useState } from 'react'; + +type UseBoolStateReturn = [ + state: boolean, + setTrue: () => void, + setFalse: () => void, + toggle: () => void +]; + +export const useBoolState = (initial = false): UseBoolStateReturn => { + const [state, setState] = useState(initial); + + const setTrue = useCallback(() => { + setState(true); + }, []); + + const setFalse = useCallback(() => { + setState(false); + }, []); + + const toggle = useCallback(() => { + setState((val) => !val); + }, []); + + return [state, setTrue, setFalse, toggle]; +}; diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_value_changed.ts b/x-pack/plugins/security_solution/public/common/hooks/use_value_changed.ts new file mode 100644 index 00000000000000..ef054d05397579 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/hooks/use_value_changed.ts @@ -0,0 +1,28 @@ +/* + * 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 { useEffect, useRef } from 'react'; + +/** + * Use this method to watch value for changes. + * + * CAUTION: you probably don't need this hook. Try to use useEffect first. + * It is only useful in rare cases when a value differs by reference but not by content between renders. + * + * @param callback A callback to call when the value changes + * @param nextValue A value to observe for changes + */ +export const useValueChanged = (callback: (value: T) => void, nextValue: T) => { + const prevValue = useRef(nextValue); + + useEffect(() => { + if (JSON.stringify(prevValue.current) !== JSON.stringify(nextValue)) { + prevValue.current = nextValue; + callback(nextValue); + } + }, [callback, nextValue]); +}; diff --git a/x-pack/plugins/security_solution/public/common/utils/download_blob.ts b/x-pack/plugins/security_solution/public/common/utils/download_blob.ts new file mode 100644 index 00000000000000..80f32a8bdaa0c1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/utils/download_blob.ts @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/** + * Method for downloading any file + * + * @param blob raw data + * @param filename of file to be downloaded + * + */ +export const downloadBlob = (blob: Blob, filename: string) => { + const objectURL = window.URL.createObjectURL(blob); + const anchor = document.createElement('a'); + anchor.href = objectURL; + anchor.download = filename; + anchor.click(); + window.URL.revokeObjectURL(objectURL); + anchor.remove(); +}; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index 3152c08fab323c..9f59e3763ffbc7 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -111,7 +111,7 @@ const AlertContextMenuComponent: React.FC = ({ setPopover(false); }, []); const [exceptionModalType, setOpenAddExceptionModal] = useState(null); - const [isAddEventExceptionModalOpen, setIsAddEventExceptionModalOpen] = useState(false); + const [isAddEventFilterModalOpen, setIsAddEventFilterModalOpen] = useState(false); const [{ canUserCRUD, hasIndexWrite, hasIndexMaintenance, hasIndexUpdateDelete }] = useUserData(); const isEndpointAlert = useMemo((): boolean => { @@ -129,8 +129,8 @@ const AlertContextMenuComponent: React.FC = ({ setOpenAddExceptionModal(null); }, []); - const closeAddEventExceptionModal = useCallback((): void => { - setIsAddEventExceptionModalOpen(false); + const closeAddEventFilterModal = useCallback((): void => { + setIsAddEventFilterModalOpen(false); }, []); const onAddExceptionCancel = useCallback(() => { @@ -364,26 +364,26 @@ const AlertContextMenuComponent: React.FC = ({ ); }, [handleAddExceptionClick, canUserCRUD, hasIndexWrite]); - const handleAddEventExceptionClick = useCallback((): void => { + const handleAddEventFilterClick = useCallback((): void => { closePopover(); - setIsAddEventExceptionModalOpen(true); + setIsAddEventFilterModalOpen(true); }, [closePopover]); - const addEventExceptionComponent = useMemo( + const addEventFilterComponent = useMemo( () => ( - - {i18n.ACTION_ADD_EVENT_EXCEPTION} + + {i18n.ACTION_ADD_EVENT_FILTER} ), - [handleAddEventExceptionClick] + [handleAddEventFilterClick] ); const statusFilters = useMemo(() => { @@ -412,11 +412,11 @@ const AlertContextMenuComponent: React.FC = ({ () => !isEvent && ruleId ? [...statusFilters, addEndpointExceptionComponent, addExceptionComponent] - : [addEventExceptionComponent], + : [addEventFilterComponent], [ addEndpointExceptionComponent, addExceptionComponent, - addEventExceptionComponent, + addEventFilterComponent, statusFilters, ruleId, isEvent, @@ -453,8 +453,8 @@ const AlertContextMenuComponent: React.FC = ({ onRuleChange={onRuleChange} /> )} - {isAddEventExceptionModalOpen && ecsRowData != null && ( - + {isAddEventFilterModalOpen && ecsRowData != null && ( + )} ); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts index 2d9f947dcea675..c43c4547a17ec6 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts @@ -165,10 +165,10 @@ export const ACTION_ADD_EXCEPTION = i18n.translate( } ); -export const ACTION_ADD_EVENT_EXCEPTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.actions.addEventException', +export const ACTION_ADD_EVENT_FILTER = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.actions.addEventFilter', { - defaultMessage: 'Add Endpoint event exception', + defaultMessage: 'Add Endpoint event filter', } ); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/all_rules_tables/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/all_rules_tables/index.test.tsx index 3400a960bbc60a..d1dfd6ccfd5657 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/all_rules_tables/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/all_rules_tables/index.test.tsx @@ -21,7 +21,7 @@ describe('AllRulesTables', () => { { { ; - hasNoPermissions: boolean; + hasPermissions: boolean; monitoringColumns: Array>; pagination: { pageIndex: number; @@ -55,7 +55,7 @@ const emptyPrompt = ( export const AllRulesTablesComponent: React.FC = ({ euiBasicTableSelectionProps, - hasNoPermissions, + hasPermissions, monitoringColumns, pagination, rules, @@ -72,7 +72,7 @@ export const AllRulesTablesComponent: React.FC = ({ = ({ pagination={pagination} ref={tableRef} sorting={sorting} - selection={hasNoPermissions ? undefined : euiBasicTableSelectionProps} + selection={hasPermissions ? euiBasicTableSelectionProps : undefined} /> )} {selectedTab === AllRulesTabs.monitoring && ( void; loading: boolean; - userHasNoPermissions: boolean; + userHasPermissions: boolean; } const PrePackagedRulesPromptComponent: React.FC = ({ createPrePackagedRules, loading = false, - userHasNoPermissions = true, + userHasPermissions = false, }) => { const history = useHistory(); const handlePreBuiltCreation = useCallback(() => { @@ -64,16 +64,17 @@ const PrePackagedRulesPromptComponent: React.FC = ( const loadPrebuiltRulesAndTemplatesButton = useMemo( () => getLoadPrebuiltRulesAndTemplatesButton({ - isDisabled: userHasNoPermissions, + isDisabled: !userHasPermissions, onClick: handlePreBuiltCreation, fill: true, 'data-test-subj': 'load-prebuilt-rules', }), - [getLoadPrebuiltRulesAndTemplatesButton, handlePreBuiltCreation, userHasNoPermissions] + [getLoadPrebuiltRulesAndTemplatesButton, handlePreBuiltCreation, userHasPermissions] ); return ( {i18n.PRE_BUILT_TITLE}} body={

{i18n.PRE_BUILT_MSG}

} actions={ @@ -81,7 +82,7 @@ const PrePackagedRulesPromptComponent: React.FC = ( {loadPrebuiltRulesAndTemplatesButton} - `; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx index 53f478da28055f..3a27469ba25397 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx @@ -28,6 +28,16 @@ jest.mock('../../../pages/detection_engine/rules/all/actions', () => ({ editRuleAction: jest.fn(), })); +jest.mock('../../../../common/lib/kibana', () => { + return { + KibanaServices: { + get: () => ({ + http: { fetch: jest.fn() }, + }), + }, + }; +}); + const duplicateRulesActionMock = duplicateRulesAction as jest.Mock; const flushPromises = () => new Promise(setImmediate); @@ -41,7 +51,7 @@ describe('RuleActionsOverflow', () => { const wrapper = shallow( ); @@ -54,7 +64,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -70,11 +80,7 @@ describe('RuleActionsOverflow', () => { test('items are empty when there is a null rule within the rules-details-menu-panel', () => { const wrapper = mount( - + ); wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); wrapper.update(); @@ -85,11 +91,7 @@ describe('RuleActionsOverflow', () => { test('items are empty when there is an undefined rule within the rules-details-menu-panel', () => { const wrapper = mount( - + ); wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); wrapper.update(); @@ -102,7 +104,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -119,7 +121,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -137,7 +139,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -152,7 +154,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -167,7 +169,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -184,7 +186,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -198,11 +200,7 @@ describe('RuleActionsOverflow', () => { test('it calls duplicateRulesAction with the rule and rule.id when rules-details-duplicate-rule is clicked', () => { const rule = mockRule('id'); const wrapper = mount( - + ); wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); wrapper.update(); @@ -222,11 +220,7 @@ describe('RuleActionsOverflow', () => { const ruleDuplicate = mockRule('newRule'); duplicateRulesActionMock.mockImplementation(() => Promise.resolve([ruleDuplicate])); const wrapper = mount( - + ); wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); wrapper.update(); @@ -244,7 +238,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -259,7 +253,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -272,33 +266,11 @@ describe('RuleActionsOverflow', () => { ).toEqual(false); }); - test('it sets the rule.rule_id on the generic downloader when rules-details-export-rule is clicked', () => { - const rule = mockRule('id'); - const wrapper = mount( - - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-export-rule"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-generic-downloader"]').prop('ids') - ).toEqual([rule.rule_id]); - }); - test('it does not close the pop over on rules-details-export-rule when the rule is an immutable rule and the user does a click', () => { const rule = mockRule('id'); rule.immutable = true; const wrapper = mount( - + ); wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); wrapper.update(); @@ -308,25 +280,6 @@ describe('RuleActionsOverflow', () => { wrapper.find('[data-test-subj="rules-details-popover"]').first().prop('isOpen') ).toEqual(true); }); - - test('it does not set the rule.rule_id on rules-details-export-rule when the rule is an immutable rule', () => { - const rule = mockRule('id'); - rule.immutable = true; - const wrapper = mount( - - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-export-rule"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-generic-downloader"]').prop('ids') - ).toEqual([]); - }); }); describe('rules details delete rule', () => { @@ -335,7 +288,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -350,7 +303,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -367,7 +320,7 @@ describe('RuleActionsOverflow', () => { const wrapper = mount( ); @@ -381,11 +334,7 @@ describe('RuleActionsOverflow', () => { test('it calls deleteRulesAction with the rule.id when rules-details-delete-rule is clicked', () => { const rule = mockRule('id'); const wrapper = mount( - + ); wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); wrapper.update(); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx index 0482e1997c9d13..e0841824d512f1 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx @@ -12,23 +12,24 @@ import { EuiPopover, EuiToolTip, } from '@elastic/eui'; -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; import { noop } from 'lodash/fp'; import { useHistory } from 'react-router-dom'; -import { Rule, exportRules } from '../../../containers/detection_engine/rules'; +import { Rule } from '../../../containers/detection_engine/rules'; import * as i18n from './translations'; import * as i18nActions from '../../../pages/detection_engine/rules/translations'; -import { displaySuccessToast, useStateToaster } from '../../../../common/components/toasters'; +import { useStateToaster } from '../../../../common/components/toasters'; import { deleteRulesAction, duplicateRulesAction, editRuleAction, + exportRulesAction, } from '../../../pages/detection_engine/rules/all/actions'; -import { GenericDownloader } from '../../../../common/components/generic_downloader'; import { getRulesUrl } from '../../../../common/components/link_to/redirect_to_detection_engine'; import { getToolTipContent } from '../../../../common/utils/privileges'; +import { useBoolState } from '../../../../common/hooks/use_bool_state'; const MyEuiButtonIcon = styled(EuiButtonIcon)` &.euiButtonIcon { @@ -43,7 +44,7 @@ const MyEuiButtonIcon = styled(EuiButtonIcon)` interface RuleActionsOverflowComponentProps { rule: Rule | null; - userHasNoPermissions: boolean; + userHasPermissions: boolean; canDuplicateRuleWithActions: boolean; } @@ -52,11 +53,10 @@ interface RuleActionsOverflowComponentProps { */ const RuleActionsOverflowComponent = ({ rule, - userHasNoPermissions, + userHasPermissions, canDuplicateRuleWithActions, }: RuleActionsOverflowComponentProps) => { - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const [rulesToExport, setRulesToExport] = useState([]); + const [isPopoverOpen, , closePopover, togglePopover] = useBoolState(); const history = useHistory(); const [, dispatchToaster] = useStateToaster(); @@ -71,10 +71,10 @@ const RuleActionsOverflowComponent = ({ { - setIsPopoverOpen(false); + closePopover(); const createdRules = await duplicateRulesAction( [rule], [rule.id], @@ -96,11 +96,11 @@ const RuleActionsOverflowComponent = ({ { - setIsPopoverOpen(false); - setRulesToExport([rule.rule_id]); + onClick={async () => { + closePopover(); + await exportRulesAction([rule.rule_id], noop, dispatchToaster); }} > {i18nActions.EXPORT_RULE} @@ -108,10 +108,10 @@ const RuleActionsOverflowComponent = ({ { - setIsPopoverOpen(false); + closePopover(); await deleteRulesAction([rule.id], noop, dispatchToaster, onRuleDeletedCallback); }} > @@ -119,27 +119,30 @@ const RuleActionsOverflowComponent = ({ , ] : [], - // eslint-disable-next-line react-hooks/exhaustive-deps - [rule, userHasNoPermissions] + [ + canDuplicateRuleWithActions, + closePopover, + dispatchToaster, + history, + onRuleDeletedCallback, + rule, + userHasPermissions, + ] ); - const handlePopoverOpen = useCallback(() => { - setIsPopoverOpen(!isPopoverOpen); - }, [setIsPopoverOpen, isPopoverOpen]); - const button = useMemo( () => ( ), - [handlePopoverOpen, userHasNoPermissions] + [togglePopover, userHasPermissions] ); return ( @@ -147,7 +150,7 @@ const RuleActionsOverflowComponent = ({ setIsPopoverOpen(false)} + closePopover={closePopover} id="ruleActionsOverflow" isOpen={isPopoverOpen} data-test-subj="rules-details-popover" @@ -157,18 +160,6 @@ const RuleActionsOverflowComponent = ({ > - { - displaySuccessToast( - i18nActions.SUCCESSFULLY_EXPORTED_RULES(exportCount), - dispatchToaster - ); - }} - /> ); }; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts index d4c4e10813172a..7de91a07a68a0b 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts @@ -13,6 +13,7 @@ import { DETECTION_ENGINE_RULES_STATUS_URL, DETECTION_ENGINE_PREPACKAGED_RULES_STATUS_URL, DETECTION_ENGINE_TAGS_URL, + DETECTION_ENGINE_RULES_BULK_ACTION, } from '../../../../../common/constants'; import { UpdateRulesProps, @@ -32,10 +33,14 @@ import { PrePackagedRulesStatusResponse, BulkRuleResponse, PatchRuleProps, + BulkActionProps, + BulkActionResponse, } from './types'; import { KibanaServices } from '../../../../common/lib/kibana'; import * as i18n from '../../../pages/detection_engine/rules/translations'; import { RulesSchema } from '../../../../../common/detection_engine/schemas/response'; +import { convertRulesFilterToKQL } from './utils'; +import { BulkAction } from '../../../../../common/detection_engine/schemas/common/schemas'; /** * Create provided Rule @@ -110,26 +115,7 @@ export const fetchRules = async ({ }, signal, }: FetchRulesProps): Promise => { - const showCustomRuleFilter = filterOptions.showCustomRules - ? [`alert.attributes.tags: "__internal_immutable:false"`] - : []; - const showElasticRuleFilter = filterOptions.showElasticRules - ? [`alert.attributes.tags: "__internal_immutable:true"`] - : []; - const filtersWithoutTags = [ - ...(filterOptions.filter.length ? [`alert.attributes.name: ${filterOptions.filter}`] : []), - ...showCustomRuleFilter, - ...showElasticRuleFilter, - ].join(' AND '); - - const tags = filterOptions.tags - .map((t) => `alert.attributes.tags: "${t.replace(/"/g, '\\"')}"`) - .join(' AND '); - - const filterString = - filtersWithoutTags !== '' && tags !== '' - ? `${filtersWithoutTags} AND (${tags})` - : filtersWithoutTags + tags; + const filterString = convertRulesFilterToKQL(filterOptions); const getFieldNameForSortField = (field: string) => { return field === 'name' ? `${field}.keyword` : field; @@ -243,6 +229,23 @@ export const duplicateRules = async ({ rules }: DuplicateRulesProps): Promise({ + action, + query, +}: BulkActionProps): Promise> => + KibanaServices.get().http.fetch>(DETECTION_ENGINE_RULES_BULK_ACTION, { + method: 'POST', + body: JSON.stringify({ action, query }), + }); + /** * Create Prepackaged Rules * diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/rules_table_reducer.test.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/rules_table_reducer.test.ts index 60edeaf0de9832..2a983117db524a 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/rules_table_reducer.test.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/rules_table_reducer.test.ts @@ -7,7 +7,7 @@ import { mockRule } from '../../../../pages/detection_engine/rules/all/__mocks__/mock'; import { FilterOptions, PaginationOptions } from '../types'; -import { RulesTableAction, RulesTableState, createRulesTableReducer } from './rules_table_reducer'; +import { RulesTableState, rulesTableReducer } from './rules_table_reducer'; const initialState: RulesTableState = { rules: [], @@ -24,10 +24,10 @@ const initialState: RulesTableState = { showCustomRules: false, showElasticRules: false, }, + isAllSelected: false, loadingRulesAction: null, loadingRuleIds: [], selectedRuleIds: [], - exportRuleIds: [], lastUpdated: 0, isRefreshOn: false, isRefreshing: false, @@ -35,36 +35,20 @@ const initialState: RulesTableState = { }; describe('allRulesReducer', () => { - let reducer: (state: RulesTableState, action: RulesTableAction) => RulesTableState; - beforeEach(() => { jest.useFakeTimers(); jest .spyOn(global.Date, 'now') .mockImplementationOnce(() => new Date('2020-10-31T11:01:58.135Z').valueOf()); - reducer = createRulesTableReducer({ current: null }); }); afterEach(() => { jest.clearAllMocks(); }); - describe('#exportRuleIds', () => { - test('should update state with rules to be exported', () => { - const { loadingRuleIds, loadingRulesAction, exportRuleIds } = reducer(initialState, { - type: 'exportRuleIds', - ids: ['123', '456'], - }); - - expect(loadingRuleIds).toEqual(['123', '456']); - expect(exportRuleIds).toEqual(['123', '456']); - expect(loadingRulesAction).toEqual('export'); - }); - }); - describe('#loadingRuleIds', () => { - test('should update state with rule ids with a pending action', () => { - const { loadingRuleIds, loadingRulesAction } = reducer(initialState, { + it('should update state with rule ids with a pending action', () => { + const { loadingRuleIds, loadingRulesAction } = rulesTableReducer(initialState, { type: 'loadingRuleIds', ids: ['123', '456'], actionType: 'enable', @@ -74,8 +58,8 @@ describe('allRulesReducer', () => { expect(loadingRulesAction).toEqual('enable'); }); - test('should update loadingIds to empty array if action is null', () => { - const { loadingRuleIds, loadingRulesAction } = reducer(initialState, { + it('should update loadingIds to empty array if action is null', () => { + const { loadingRuleIds, loadingRulesAction } = rulesTableReducer(initialState, { type: 'loadingRuleIds', ids: ['123', '456'], actionType: null, @@ -85,8 +69,8 @@ describe('allRulesReducer', () => { expect(loadingRulesAction).toBeNull(); }); - test('should append rule ids to any existing loading ids', () => { - const { loadingRuleIds, loadingRulesAction } = reducer( + it('should append rule ids to any existing loading ids', () => { + const { loadingRuleIds, loadingRulesAction } = rulesTableReducer( { ...initialState, loadingRuleIds: ['abc'] }, { type: 'loadingRuleIds', @@ -101,8 +85,8 @@ describe('allRulesReducer', () => { }); describe('#selectedRuleIds', () => { - test('should update state with selected rule ids', () => { - const { selectedRuleIds } = reducer(initialState, { + it('should update state with selected rule ids', () => { + const { selectedRuleIds } = rulesTableReducer(initialState, { type: 'selectedRuleIds', ids: ['123', '456'], }); @@ -112,19 +96,22 @@ describe('allRulesReducer', () => { }); describe('#setRules', () => { - test('should update rules and reset loading/selected rule ids', () => { - const { selectedRuleIds, loadingRuleIds, loadingRulesAction, pagination, rules } = reducer( - initialState, - { - type: 'setRules', - rules: [mockRule('someRuleId')], - pagination: { - page: 1, - perPage: 20, - total: 0, - }, - } - ); + it('should update rules and reset loading/selected rule ids', () => { + const { + selectedRuleIds, + loadingRuleIds, + loadingRulesAction, + pagination, + rules, + } = rulesTableReducer(initialState, { + type: 'setRules', + rules: [mockRule('someRuleId')], + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + }); expect(rules).toEqual([mockRule('someRuleId')]); expect(selectedRuleIds).toEqual([]); @@ -139,9 +126,9 @@ describe('allRulesReducer', () => { }); describe('#updateRules', () => { - test('should return existing and new rules', () => { + it('should return existing and new rules', () => { const existingRule = { ...mockRule('123'), rule_id: 'rule-123' }; - const { rules, loadingRulesAction } = reducer( + const { rules, loadingRulesAction } = rulesTableReducer( { ...initialState, rules: [existingRule] }, { type: 'updateRules', @@ -153,9 +140,9 @@ describe('allRulesReducer', () => { expect(loadingRulesAction).toBeNull(); }); - test('should return updated rule', () => { + it('should return updated rule', () => { const updatedRule = { ...mockRule('someRuleId'), description: 'updated rule' }; - const { rules, loadingRulesAction } = reducer( + const { rules, loadingRulesAction } = rulesTableReducer( { ...initialState, rules: [mockRule('someRuleId')] }, { type: 'updateRules', @@ -167,9 +154,9 @@ describe('allRulesReducer', () => { expect(loadingRulesAction).toBeNull(); }); - test('should return updated existing loading rule ids', () => { + it('should return updated existing loading rule ids', () => { const existingRule = { ...mockRule('someRuleId'), id: '123', rule_id: 'rule-123' }; - const { loadingRuleIds, loadingRulesAction } = reducer( + const { loadingRuleIds, loadingRulesAction } = rulesTableReducer( { ...initialState, rules: [existingRule], @@ -188,7 +175,7 @@ describe('allRulesReducer', () => { }); describe('#updateFilterOptions', () => { - test('should return existing and new rules', () => { + it('should return existing and new rules', () => { const paginationMock: PaginationOptions = { page: 1, perPage: 20, @@ -202,7 +189,7 @@ describe('allRulesReducer', () => { showCustomRules: false, showElasticRules: false, }; - const { filterOptions, pagination } = reducer(initialState, { + const { filterOptions, pagination } = rulesTableReducer(initialState, { type: 'updateFilterOptions', filterOptions: filterMock, pagination: paginationMock, @@ -214,8 +201,8 @@ describe('allRulesReducer', () => { }); describe('#failure', () => { - test('should reset rules value to empty array', () => { - const { rules } = reducer(initialState, { + it('should reset rules value to empty array', () => { + const { rules } = rulesTableReducer(initialState, { type: 'failure', }); @@ -224,8 +211,8 @@ describe('allRulesReducer', () => { }); describe('#setLastRefreshDate', () => { - test('should update last refresh date with current date', () => { - const { lastUpdated } = reducer(initialState, { + it('should update last refresh date with current date', () => { + const { lastUpdated } = rulesTableReducer(initialState, { type: 'setLastRefreshDate', }); @@ -234,8 +221,8 @@ describe('allRulesReducer', () => { }); describe('#setShowIdleModal', () => { - test('should hide idle modal and restart refresh if "show" is false', () => { - const { showIdleModal, isRefreshOn } = reducer(initialState, { + it('should hide idle modal and restart refresh if "show" is false', () => { + const { showIdleModal, isRefreshOn } = rulesTableReducer(initialState, { type: 'setShowIdleModal', show: false, }); @@ -244,8 +231,8 @@ describe('allRulesReducer', () => { expect(isRefreshOn).toBeTruthy(); }); - test('should show idle modal and pause refresh if "show" is true', () => { - const { showIdleModal, isRefreshOn } = reducer(initialState, { + it('should show idle modal and pause refresh if "show" is true', () => { + const { showIdleModal, isRefreshOn } = rulesTableReducer(initialState, { type: 'setShowIdleModal', show: true, }); @@ -256,8 +243,8 @@ describe('allRulesReducer', () => { }); describe('#setAutoRefreshOn', () => { - test('should pause auto refresh if "paused" is true', () => { - const { isRefreshOn } = reducer(initialState, { + it('should pause auto refresh if "paused" is true', () => { + const { isRefreshOn } = rulesTableReducer(initialState, { type: 'setAutoRefreshOn', on: true, }); @@ -265,8 +252,8 @@ describe('allRulesReducer', () => { expect(isRefreshOn).toBeTruthy(); }); - test('should resume auto refresh if "paused" is false', () => { - const { isRefreshOn } = reducer(initialState, { + it('should resume auto refresh if "paused" is false', () => { + const { isRefreshOn } = rulesTableReducer(initialState, { type: 'setAutoRefreshOn', on: false, }); @@ -274,4 +261,58 @@ describe('allRulesReducer', () => { expect(isRefreshOn).toBeFalsy(); }); }); + + describe('#selectAllRules', () => { + it('should select all rules', () => { + const state = rulesTableReducer( + { + ...initialState, + rules: [mockRule('1'), mockRule('2'), mockRule('3')], + }, + { + type: 'setIsAllSelected', + isAllSelected: true, + } + ); + + expect(state.isAllSelected).toBe(true); + expect(state.selectedRuleIds).toEqual(['1', '2', '3']); + }); + + it('should deselect all rules', () => { + const state = rulesTableReducer( + { + ...initialState, + rules: [mockRule('1'), mockRule('2'), mockRule('3')], + isAllSelected: true, + selectedRuleIds: ['1', '2', '3'], + }, + { + type: 'setIsAllSelected', + isAllSelected: false, + } + ); + + expect(state.isAllSelected).toBe(false); + expect(state.selectedRuleIds).toEqual([]); + }); + + it('should unset "isAllSelected" on selected rules modification', () => { + const state = rulesTableReducer( + { + ...initialState, + rules: [mockRule('1'), mockRule('2'), mockRule('3')], + isAllSelected: true, + selectedRuleIds: ['1', '2', '3'], + }, + { + type: 'selectedRuleIds', + ids: ['1', '2'], + } + ); + + expect(state.isAllSelected).toBe(false); + expect(state.selectedRuleIds).toEqual(['1', '2']); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/rules_table_reducer.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/rules_table_reducer.ts index 01a87fef2b723d..7d32785222fed5 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/rules_table_reducer.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/rules_table_reducer.ts @@ -5,8 +5,6 @@ * 2.0. */ -import type React from 'react'; -import { EuiBasicTable } from '@elastic/eui'; import { FilterOptions, PaginationOptions, Rule } from '../types'; export type LoadingRuleAction = @@ -25,11 +23,11 @@ export interface RulesTableState { loadingRulesAction: LoadingRuleAction; loadingRuleIds: string[]; selectedRuleIds: string[]; - exportRuleIds: string[]; lastUpdated: number; isRefreshOn: boolean; isRefreshing: boolean; showIdleModal: boolean; + isAllSelected: boolean; } export type RulesTableAction = @@ -42,128 +40,119 @@ export type RulesTableAction = } | { type: 'loadingRuleIds'; ids: string[]; actionType: LoadingRuleAction } | { type: 'selectedRuleIds'; ids: string[] } - | { type: 'exportRuleIds'; ids: string[] } | { type: 'setLastRefreshDate' } | { type: 'setAutoRefreshOn'; on: boolean } | { type: 'setIsRefreshing'; isRefreshing: boolean } + | { type: 'setIsAllSelected'; isAllSelected: boolean } | { type: 'setShowIdleModal'; show: boolean } | { type: 'failure' }; -export const createRulesTableReducer = ( - tableRef: React.MutableRefObject | null> -) => { - const rulesTableReducer = (state: RulesTableState, action: RulesTableAction): RulesTableState => { - switch (action.type) { - case 'setRules': { - if (tableRef?.current?.changeSelection != null) { - // for future devs: eui basic table is not giving us a prop to set the value, so - // we are using the ref in setTimeout to reset on the next loop so that we - // do not get a warning telling us we are trying to update during a render - window.setTimeout(() => tableRef?.current?.changeSelection([]), 0); +export const rulesTableReducer = ( + state: RulesTableState, + action: RulesTableAction +): RulesTableState => { + switch (action.type) { + case 'setRules': { + return { + ...state, + rules: action.rules, + selectedRuleIds: state.isAllSelected ? action.rules.map(({ id }) => id) : [], + loadingRuleIds: [], + loadingRulesAction: null, + pagination: { + ...state.pagination, + ...action.pagination, + }, + }; + } + case 'updateRules': { + const ruleIds = state.rules.map((r) => r.id); + const updatedRules = action.rules.reduce((rules, updatedRule) => { + let newRules = rules; + if (ruleIds.includes(updatedRule.id)) { + newRules = newRules.map((r) => (updatedRule.id === r.id ? updatedRule : r)); + } else { + newRules = [...newRules, updatedRule]; } - - return { - ...state, - rules: action.rules, - selectedRuleIds: [], - loadingRuleIds: [], - loadingRulesAction: null, - pagination: { - ...state.pagination, - ...action.pagination, - }, - }; - } - case 'updateRules': { - const ruleIds = state.rules.map((r) => r.id); - const updatedRules = action.rules.reduce((rules, updatedRule) => { - let newRules = rules; - if (ruleIds.includes(updatedRule.id)) { - newRules = newRules.map((r) => (updatedRule.id === r.id ? updatedRule : r)); - } else { - newRules = [...newRules, updatedRule]; - } - return newRules; - }, state.rules); - const updatedRuleIds = action.rules.map((r) => r.id); - const newLoadingRuleIds = state.loadingRuleIds.filter((id) => !updatedRuleIds.includes(id)); - return { - ...state, - rules: updatedRules, - loadingRuleIds: newLoadingRuleIds, - loadingRulesAction: newLoadingRuleIds.length === 0 ? null : state.loadingRulesAction, - }; - } - case 'updateFilterOptions': { - return { - ...state, - filterOptions: { - ...state.filterOptions, - ...action.filterOptions, - }, - pagination: { - ...state.pagination, - ...action.pagination, - }, - }; - } - case 'loadingRuleIds': { - return { - ...state, - loadingRuleIds: action.actionType == null ? [] : [...state.loadingRuleIds, ...action.ids], - loadingRulesAction: action.actionType, - }; - } - case 'selectedRuleIds': { - return { - ...state, - selectedRuleIds: action.ids, - }; - } - case 'exportRuleIds': { - return { - ...state, - loadingRuleIds: action.ids, - loadingRulesAction: 'export', - exportRuleIds: action.ids, - }; - } - case 'setLastRefreshDate': { - return { - ...state, - lastUpdated: Date.now(), - }; - } - case 'setAutoRefreshOn': { - return { - ...state, - isRefreshOn: action.on, - }; - } - case 'setIsRefreshing': { - return { - ...state, - isRefreshing: action.isRefreshing, - }; - } - case 'setShowIdleModal': { - return { - ...state, - showIdleModal: action.show, - isRefreshOn: !action.show, - }; - } - case 'failure': { - return { - ...state, - rules: [], - }; - } - default: { - return state; - } + return newRules; + }, state.rules); + const updatedRuleIds = action.rules.map((r) => r.id); + const newLoadingRuleIds = state.loadingRuleIds.filter((id) => !updatedRuleIds.includes(id)); + return { + ...state, + rules: updatedRules, + loadingRuleIds: newLoadingRuleIds, + loadingRulesAction: newLoadingRuleIds.length === 0 ? null : state.loadingRulesAction, + }; } - }; - - return rulesTableReducer; + case 'updateFilterOptions': { + return { + ...state, + filterOptions: { + ...state.filterOptions, + ...action.filterOptions, + }, + pagination: { + ...state.pagination, + ...action.pagination, + }, + }; + } + case 'loadingRuleIds': { + return { + ...state, + loadingRuleIds: action.actionType == null ? [] : [...state.loadingRuleIds, ...action.ids], + loadingRulesAction: action.actionType, + }; + } + case 'selectedRuleIds': { + return { + ...state, + isAllSelected: false, + selectedRuleIds: action.ids, + }; + } + case 'setLastRefreshDate': { + return { + ...state, + lastUpdated: Date.now(), + }; + } + case 'setAutoRefreshOn': { + return { + ...state, + isRefreshOn: action.on, + }; + } + case 'setIsRefreshing': { + return { + ...state, + isRefreshing: action.isRefreshing, + }; + } + case 'setIsAllSelected': { + const { isAllSelected } = action; + return { + ...state, + isAllSelected, + selectedRuleIds: isAllSelected ? state.rules.map(({ id }) => id) : [], + }; + } + case 'setShowIdleModal': { + return { + ...state, + showIdleModal: action.show, + isRefreshOn: !action.show, + }; + } + case 'failure': { + return { + ...state, + rules: [], + }; + } + default: { + return state; + } + } }; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/use_async_confirmation.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/use_async_confirmation.ts new file mode 100644 index 00000000000000..cce45f87d8ce38 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/use_async_confirmation.ts @@ -0,0 +1,46 @@ +/* + * 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 { useCallback, useRef } from 'react'; + +type UseAsyncConfirmationReturn = [ + initConfirmation: () => Promise, + confirm: () => void, + cancel: () => void +]; + +interface UseAsyncConfirmationArgs { + onInit: () => void; + onFinish: () => void; +} + +export const useAsyncConfirmation = ({ + onInit, + onFinish, +}: UseAsyncConfirmationArgs): UseAsyncConfirmationReturn => { + const confirmationPromiseRef = useRef<(result: boolean) => void>(); + + const confirm = useCallback(() => { + confirmationPromiseRef.current?.(true); + }, []); + + const cancel = useCallback(() => { + confirmationPromiseRef.current?.(false); + }, []); + + const initConfirmation = useCallback(() => { + onInit(); + + return new Promise((resolve) => { + confirmationPromiseRef.current = resolve; + }).finally(() => { + onFinish(); + }); + }, [onInit, onFinish]); + + return [initConfirmation, confirm, cancel]; +}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/use_rules_table.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/use_rules_table.ts index 8969843f61a1cd..cb41401ee2f40a 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/use_rules_table.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/rules_table/use_rules_table.ts @@ -5,14 +5,11 @@ * 2.0. */ -import { Dispatch, useMemo, useReducer, useEffect, useRef } from 'react'; -import { EuiBasicTable } from '@elastic/eui'; - +import { Dispatch, useReducer, useEffect, useRef } from 'react'; import { useAppToasts } from '../../../../../common/hooks/use_app_toasts'; import * as i18n from '../translations'; - import { fetchRules } from '../api'; -import { createRulesTableReducer, RulesTableState, RulesTableAction } from './rules_table_reducer'; +import { rulesTableReducer, RulesTableState, RulesTableAction } from './rules_table_reducer'; import { createRulesTableFacade, RulesTableFacade } from './rules_table_facade'; const INITIAL_SORT_FIELD = 'enabled'; @@ -35,15 +32,14 @@ const initialStateDefaults: RulesTableState = { loadingRulesAction: null, loadingRuleIds: [], selectedRuleIds: [], - exportRuleIds: [], lastUpdated: 0, isRefreshOn: true, isRefreshing: false, + isAllSelected: false, showIdleModal: false, }; export interface UseRulesTableParams { - tableRef: React.MutableRefObject | null>; initialStateOverride?: Partial; } @@ -54,7 +50,7 @@ export interface UseRulesTableReturn extends RulesTableFacade { } export const useRulesTable = (params: UseRulesTableParams): UseRulesTableReturn => { - const { tableRef, initialStateOverride } = params; + const { initialStateOverride } = params; const initialState: RulesTableState = { ...initialStateDefaults, @@ -62,8 +58,7 @@ export const useRulesTable = (params: UseRulesTableParams): UseRulesTableReturn ...initialStateOverride, }; - const reducer = useMemo(() => createRulesTableReducer(tableRef), [tableRef]); - const [state, dispatch] = useReducer(reducer, initialState); + const [state, dispatch] = useReducer(rulesTableReducer, initialState); const facade = useRef(createRulesTableFacade(dispatch)); const { addError } = useAppToasts(); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts index 85ff0f9ac14579..20bdeaf7e63787 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts @@ -28,6 +28,7 @@ import { rule_name_override, timestamp_override, threshold, + BulkAction, } from '../../../../../common/detection_engine/schemas/common/schemas'; import { CreateRulesSchema, @@ -212,6 +213,24 @@ export interface DuplicateRulesProps { rules: Rule[]; } +export interface BulkActionProps { + action: Action; + query: string; +} + +export interface BulkActionResult { + success: boolean; + rules_count: number; +} + +export type BulkActionResponse = { + [BulkAction.delete]: BulkActionResult; + [BulkAction.disable]: BulkActionResult; + [BulkAction.enable]: BulkActionResult; + [BulkAction.duplicate]: BulkActionResult; + [BulkAction.export]: Blob; +}[Action]; + export interface BasicFetchProps { signal: AbortSignal; } @@ -248,7 +267,7 @@ export interface ExportDocumentsProps { ids: string[]; filename?: string; excludeExportDetails?: boolean; - signal: AbortSignal; + signal?: AbortSignal; } export interface RuleStatus { diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.test.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.test.ts new file mode 100644 index 00000000000000..c293e26f1740c6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.test.ts @@ -0,0 +1,64 @@ +/* + * 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 { INTERNAL_IMMUTABLE_KEY } from '../../../../../common/constants'; +import { FilterOptions } from './types'; +import { convertRulesFilterToKQL } from './utils'; + +describe('convertRulesFilterToKQL', () => { + const filterOptions: FilterOptions = { + filter: '', + sortField: 'name', + sortOrder: 'asc', + showCustomRules: false, + showElasticRules: false, + tags: [], + }; + + it('returns empty string if filter options are empty', () => { + const kql = convertRulesFilterToKQL(filterOptions); + + expect(kql).toBe(''); + }); + + it('handles presence of "filter" properly', () => { + const kql = convertRulesFilterToKQL({ ...filterOptions, filter: 'foo' }); + + expect(kql).toBe('alert.attributes.name: foo'); + }); + + it('handles presence of "showCustomRules" properly', () => { + const kql = convertRulesFilterToKQL({ ...filterOptions, showCustomRules: true }); + + expect(kql).toBe(`alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:false"`); + }); + + it('handles presence of "showElasticRules" properly', () => { + const kql = convertRulesFilterToKQL({ ...filterOptions, showElasticRules: true }); + + expect(kql).toBe(`alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:true"`); + }); + + it('handles presence of "tags" properly', () => { + const kql = convertRulesFilterToKQL({ ...filterOptions, tags: ['tag1', 'tag2'] }); + + expect(kql).toBe('alert.attributes.tags: "tag1" AND alert.attributes.tags: "tag2"'); + }); + + it('handles combination of different properties properly', () => { + const kql = convertRulesFilterToKQL({ + ...filterOptions, + filter: 'foo', + showElasticRules: true, + tags: ['tag1', 'tag2'], + }); + + expect(kql).toBe( + `alert.attributes.name: foo AND alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:true" AND (alert.attributes.tags: "tag1" AND alert.attributes.tags: "tag2")` + ); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.ts new file mode 100644 index 00000000000000..841b2adca09e04 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.ts @@ -0,0 +1,41 @@ +/* + * 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 { INTERNAL_IMMUTABLE_KEY } from '../../../../../common/constants'; +import { FilterOptions } from './types'; + +/** + * Convert rules filter options object to KQL query + * + * @param filterOptions desired filters (e.g. filter/sortField/sortOrder) + * + * @returns KQL string + */ +export const convertRulesFilterToKQL = (filterOptions: FilterOptions): string => { + const showCustomRuleFilter = filterOptions.showCustomRules + ? [`alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:false"`] + : []; + const showElasticRuleFilter = filterOptions.showElasticRules + ? [`alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:true"`] + : []; + const filtersWithoutTags = [ + ...(filterOptions.filter.length ? [`alert.attributes.name: ${filterOptions.filter}`] : []), + ...showCustomRuleFilter, + ...showElasticRuleFilter, + ].join(' AND '); + + const tags = filterOptions.tags + .map((t) => `alert.attributes.tags: "${t.replace(/"/g, '\\"')}"`) + .join(' AND '); + + const filterString = + filtersWithoutTags !== '' && tags !== '' + ? `${filtersWithoutTags} AND (${tags})` + : filtersWithoutTags + tags; + + return filterString; +}; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.tsx index de33d414398a87..78fac10815d455 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.tsx @@ -7,29 +7,29 @@ import * as H from 'history'; import React, { Dispatch } from 'react'; - +import { BulkAction } from '../../../../../../common/detection_engine/schemas/common/schemas'; import { CreateRulesSchema } from '../../../../../../common/detection_engine/schemas/request'; -import { - deleteRules, - duplicateRules, - enableRules, - Rule, - RulesTableAction, -} from '../../../../containers/detection_engine/rules'; - import { getEditRuleUrl } from '../../../../../common/components/link_to/redirect_to_detection_engine'; - import { ActionToaster, displayErrorToast, displaySuccessToast, errorToToaster, } from '../../../../../common/components/toasters'; -import { track, METRIC_TYPE, TELEMETRY_EVENT } from '../../../../../common/lib/telemetry'; - -import * as i18n from '../translations'; -import { bucketRulesResponse } from './helpers'; +import { METRIC_TYPE, TELEMETRY_EVENT, track } from '../../../../../common/lib/telemetry'; +import { downloadBlob } from '../../../../../common/utils/download_blob'; +import { + deleteRules, + duplicateRules, + enableRules, + exportRules, + performBulkAction, + Rule, + RulesTableAction, +} from '../../../../containers/detection_engine/rules'; import { transformOutput } from '../../../../containers/detection_engine/rules/transforms'; +import * as i18n from '../translations'; +import { bucketRulesResponse, getExportedRulesCount } from './helpers'; export const editRuleAction = (rule: Rule, history: H.History) => { history.push(getEditRuleUrl(rule.id)); @@ -58,20 +58,34 @@ export const duplicateRulesAction = async ( } else { displaySuccessToast(i18n.SUCCESSFULLY_DUPLICATED_RULES(ruleIds.length), dispatchToaster); } - dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); - return createdRules; } catch (error) { - dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); errorToToaster({ title: i18n.DUPLICATE_RULE_ERROR, error, dispatchToaster }); + } finally { + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); } }; -export const exportRulesAction = ( +export const exportRulesAction = async ( exportRuleId: string[], - dispatch: React.Dispatch + dispatch: React.Dispatch, + dispatchToaster: Dispatch ) => { - dispatch({ type: 'exportRuleIds', ids: exportRuleId }); + try { + dispatch({ type: 'loadingRuleIds', ids: exportRuleId, actionType: 'export' }); + const blob = await exportRules({ ids: exportRuleId }); + downloadBlob(blob, `${i18n.EXPORT_FILENAME}.ndjson`); + + const exportedRulesCount = await getExportedRulesCount(blob); + displaySuccessToast( + i18n.SUCCESSFULLY_EXPORTED_RULES(exportedRulesCount, exportRuleId.length), + dispatchToaster + ); + } catch (e) { + displayErrorToast(i18n.BULK_ACTION_FAILED, [e.message], dispatchToaster); + } finally { + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); + } }; export const deleteRulesAction = async ( @@ -84,7 +98,6 @@ export const deleteRulesAction = async ( dispatch({ type: 'loadingRuleIds', ids: ruleIds, actionType: 'delete' }); const response = await deleteRules({ ids: ruleIds }); const { errors } = bucketRulesResponse(response); - dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); if (errors.length > 0) { displayErrorToast( i18n.BATCH_ACTION_DELETE_SELECTED_ERROR(ruleIds.length), @@ -95,12 +108,13 @@ export const deleteRulesAction = async ( onRuleDeleted(); } } catch (error) { - dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); errorToToaster({ title: i18n.BATCH_ACTION_DELETE_SELECTED_ERROR(ruleIds.length), error, dispatchToaster, }); + } finally { + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); } }; @@ -144,6 +158,37 @@ export const enableRulesAction = async ( } } catch (e) { displayErrorToast(errorTitle, [e.message], dispatchToaster); + } finally { + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); + } +}; + +export const rulesBulkActionByQuery = async ( + visibleRuleIds: string[], + selectedItemsCount: number, + query: string, + action: BulkAction, + dispatch: React.Dispatch, + dispatchToaster: Dispatch +) => { + try { + dispatch({ type: 'loadingRuleIds', ids: visibleRuleIds, actionType: action }); + + if (action === BulkAction.export) { + const blob = await performBulkAction({ query, action }); + downloadBlob(blob, `${i18n.EXPORT_FILENAME}.ndjson`); + + const exportedRulesCount = await getExportedRulesCount(blob); + displaySuccessToast( + i18n.SUCCESSFULLY_EXPORTED_RULES(exportedRulesCount, selectedItemsCount), + dispatchToaster + ); + } else { + await performBulkAction({ query, action }); + } + } catch (e) { + displayErrorToast(i18n.BULK_ACTION_FAILED, [e.message], dispatchToaster); + } finally { dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); } }; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/batch_actions.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/batch_actions.tsx index 648d653d6a3c84..5b558824b4659a 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/batch_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/batch_actions.tsx @@ -10,6 +10,7 @@ import React, { Dispatch } from 'react'; import * as i18n from '../translations'; import { RulesTableAction } from '../../../../containers/detection_engine/rules/rules_table'; import { + rulesBulkActionByQuery, deleteRulesAction, duplicateRulesAction, enableRulesAction, @@ -20,6 +21,7 @@ import { Rule } from '../../../../containers/detection_engine/rules'; import * as detectionI18n from '../../translations'; import { isMlRule } from '../../../../../../common/machine_learning/helpers'; import { canEditRuleWithActions } from '../../../../../common/utils/privileges'; +import { BulkAction } from '../../../../../../common/detection_engine/schemas/common/schemas'; interface GetBatchItems { closePopover: () => void; @@ -32,6 +34,10 @@ interface GetBatchItems { refetchPrePackagedRulesStatus: () => Promise; rules: Rule[]; selectedRuleIds: string[]; + isAllSelected: boolean; + filterQuery: string; + confirmDeletion: () => Promise; + selectedItemsCount: number; } export const getBatchItems = ({ @@ -45,51 +51,138 @@ export const getBatchItems = ({ rules, selectedRuleIds, hasActionsPrivileges, + isAllSelected, + filterQuery, + confirmDeletion, + selectedItemsCount, }: GetBatchItems) => { - const selectedRules = selectedRuleIds.reduce>((acc, id) => { - const found = rules.find((r) => r.id === id); - if (found != null) { - return { [id]: found, ...acc }; - } - return acc; - }, {}); + const selectedRules = rules.filter(({ id }) => selectedRuleIds.includes(id)); - const containsEnabled = selectedRuleIds.some((id) => selectedRules[id]?.enabled ?? false); - const containsDisabled = selectedRuleIds.some((id) => !selectedRules[id]?.enabled ?? false); + const containsEnabled = selectedRules.some(({ enabled }) => enabled); + const containsDisabled = selectedRules.some(({ enabled }) => !enabled); const containsLoading = selectedRuleIds.some((id) => loadingRuleIds.includes(id)); - const containsImmutable = selectedRuleIds.some((id) => selectedRules[id]?.immutable ?? false); + const containsImmutable = selectedRules.some(({ immutable }) => immutable); const missingActionPrivileges = !hasActionsPrivileges && - selectedRuleIds.some((id) => { - return !canEditRuleWithActions(selectedRules[id], hasActionsPrivileges); - }); + selectedRules.some((rule) => !canEditRuleWithActions(rule, hasActionsPrivileges)); + + const handleActivateAction = async () => { + closePopover(); + const deactivatedRules = selectedRules.filter(({ enabled }) => !enabled); + const deactivatedRulesNoML = deactivatedRules.filter(({ type }) => !isMlRule(type)); + + const mlRuleCount = deactivatedRules.length - deactivatedRulesNoML.length; + if (!hasMlPermissions && mlRuleCount > 0) { + displayWarningToast(detectionI18n.ML_RULES_UNAVAILABLE(mlRuleCount), dispatchToaster); + } + + const ruleIds = hasMlPermissions + ? deactivatedRules.map(({ id }) => id) + : deactivatedRulesNoML.map(({ id }) => id); + + if (isAllSelected) { + await rulesBulkActionByQuery( + ruleIds, + selectedItemsCount, + filterQuery, + BulkAction.enable, + dispatch, + dispatchToaster + ); + await reFetchRules(); + } else { + await enableRulesAction(ruleIds, true, dispatch, dispatchToaster); + } + }; + + const handleDeactivateActions = async () => { + closePopover(); + const activatedIds = selectedRules.filter(({ enabled }) => enabled).map(({ id }) => id); + if (isAllSelected) { + await rulesBulkActionByQuery( + activatedIds, + selectedItemsCount, + filterQuery, + BulkAction.disable, + dispatch, + dispatchToaster + ); + await reFetchRules(); + } else { + await enableRulesAction(activatedIds, false, dispatch, dispatchToaster); + } + }; + + const handleDuplicateAction = async () => { + closePopover(); + if (isAllSelected) { + await rulesBulkActionByQuery( + selectedRuleIds, + selectedItemsCount, + filterQuery, + BulkAction.duplicate, + dispatch, + dispatchToaster + ); + await reFetchRules(); + } else { + await duplicateRulesAction(selectedRules, selectedRuleIds, dispatch, dispatchToaster); + } + await reFetchRules(); + await refetchPrePackagedRulesStatus(); + }; + + const handleDeleteAction = async () => { + closePopover(); + if (isAllSelected) { + if ((await confirmDeletion()) === false) { + // User has cancelled deletion + return; + } + + await rulesBulkActionByQuery( + selectedRuleIds, + selectedItemsCount, + filterQuery, + BulkAction.delete, + dispatch, + dispatchToaster + ); + } else { + await deleteRulesAction(selectedRuleIds, dispatch, dispatchToaster); + } + await reFetchRules(); + await refetchPrePackagedRulesStatus(); + }; + + const handleExportAction = async () => { + closePopover(); + if (isAllSelected) { + await rulesBulkActionByQuery( + selectedRuleIds, + selectedItemsCount, + filterQuery, + BulkAction.export, + dispatch, + dispatchToaster + ); + } else { + await exportRulesAction( + selectedRules.map((r) => r.rule_id), + dispatch, + dispatchToaster + ); + } + }; return [ { - closePopover(); - const deactivatedIds = selectedRuleIds.filter((id) => !selectedRules[id]?.enabled ?? false); - - const deactivatedIdsNoML = deactivatedIds.filter( - (id) => !isMlRule(selectedRules[id]?.type) - ); - - const mlRuleCount = deactivatedIds.length - deactivatedIdsNoML.length; - if (!hasMlPermissions && mlRuleCount > 0) { - displayWarningToast(detectionI18n.ML_RULES_UNAVAILABLE(mlRuleCount), dispatchToaster); - } - - await enableRulesAction( - hasMlPermissions ? deactivatedIds : deactivatedIdsNoML, - true, - dispatch, - dispatchToaster - ); - }} + disabled={missingActionPrivileges || containsLoading || (!containsDisabled && !isAllSelected)} + onClick={handleActivateAction} > , { - closePopover(); - const activatedIds = selectedRuleIds.filter((id) => selectedRules[id]?.enabled ?? false); - await enableRulesAction(activatedIds, false, dispatch, dispatchToaster); - }} + disabled={missingActionPrivileges || containsLoading || (!containsEnabled && !isAllSelected)} + onClick={handleDeactivateActions} > , { - closePopover(); - exportRulesAction( - rules.filter((r) => selectedRuleIds.includes(r.id)).map((r) => r.rule_id), - dispatch - ); - }} + disabled={ + (containsImmutable && !isAllSelected) || containsLoading || selectedRuleIds.length === 0 + } + onClick={handleExportAction} > {i18n.BATCH_ACTION_EXPORT_SELECTED} , @@ -135,17 +222,7 @@ export const getBatchItems = ({ data-test-subj="duplicateRuleBulk" icon="copy" disabled={missingActionPrivileges || containsLoading || selectedRuleIds.length === 0} - onClick={async () => { - closePopover(); - await duplicateRulesAction( - rules.filter((r) => selectedRuleIds.includes(r.id)), - selectedRuleIds, - dispatch, - dispatchToaster - ); - await reFetchRules(); - await refetchPrePackagedRulesStatus(); - }} + onClick={handleDuplicateAction} > { - closePopover(); - await deleteRulesAction(selectedRuleIds, dispatch, dispatchToaster); - await reFetchRules(); - await refetchPrePackagedRulesStatus(); - }} + onClick={handleDeleteAction} > {i18n.BATCH_ACTION_DELETE_SELECTED} , diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx index 83bb530827fa2a..28a65c3e64e1f8 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx @@ -96,7 +96,7 @@ export const getActions = ( description: i18n.EXPORT_RULE, icon: 'exportAction', name: i18n.EXPORT_RULE, - onClick: (rowItem: Rule) => exportRulesAction([rowItem.rule_id], dispatch), + onClick: (rowItem: Rule) => exportRulesAction([rowItem.rule_id], dispatch, dispatchToaster), enabled: (rowItem: Rule) => !rowItem.immutable, }, { @@ -125,7 +125,7 @@ interface GetColumns { formatUrl: FormatUrl; history: H.History; hasMlPermissions: boolean; - hasNoPermissions: boolean; + hasPermissions: boolean; loadingRuleIds: string[]; reFetchRules: () => Promise; refetchPrePackagedRulesStatus: () => Promise; @@ -142,7 +142,7 @@ export const getColumns = ({ formatUrl, history, hasMlPermissions, - hasNoPermissions, + hasPermissions, loadingRuleIds, reFetchRules, refetchPrePackagedRulesStatus, @@ -275,7 +275,7 @@ export const getColumns = ({ enabled={item.enabled} isDisabled={ !canEditRuleWithActions(item, hasReadActionsPrivileges) || - hasNoPermissions || + !hasPermissions || (isMlRule(item.type) && !hasMlPermissions && !item.enabled) } isLoading={loadingRuleIds.includes(item.id)} @@ -300,7 +300,7 @@ export const getColumns = ({ } as EuiTableActionsColumnType, ]; - return hasNoPermissions ? cols : [...cols, ...actions]; + return hasPermissions ? [...cols, ...actions] : cols; }; export const getMonitoringColumns = ( diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx index 6a0f4dc4e2dea0..dd3549ea20d365 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx @@ -79,7 +79,7 @@ describe('ExceptionListsTable', () => { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx index 1dfa83da1637a7..7f734b10fd0200 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx @@ -38,7 +38,7 @@ export type Func = () => Promise; interface ExceptionListsTableProps { history: History; - hasNoPermissions: boolean; + hasPermissions: boolean; loading: boolean; formatUrl: FormatUrl; } @@ -60,7 +60,7 @@ const exceptionReferenceModalInitialState: ReferenceModalState = { }; export const ExceptionListsTable = React.memo( - ({ formatUrl, history, hasNoPermissions, loading }) => { + ({ formatUrl, history, hasPermissions, loading }) => { const { services: { http, notifications }, } = useKibana(); @@ -359,7 +359,7 @@ export const ExceptionListsTable = React.memo( <> ( => { + const blobContent = await blob.text(); + // The Blob content is an NDJSON file, the last line of which contains export details. + const exportDetailsJson = blobContent.split('\n').filter(Boolean).slice(-1)[0]; + const exportDetails = JSON.parse(exportDetailsJson); + + return exportDetails.exported_count; +}; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx index 1f4586754cb337..9597c221843be7 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx @@ -124,10 +124,10 @@ describe('AllRules', () => { loadingRulesAction: null, loadingRuleIds: [], selectedRuleIds: [], - exportRuleIds: [], lastUpdated: 0, isRefreshOn: true, isRefreshing: false, + isAllSelected: false, showIdleModal: false, }; @@ -189,7 +189,7 @@ describe('AllRules', () => { const wrapper = shallow( { { { { { Promise; @@ -64,7 +64,7 @@ const allRulesTabs = [ export const AllRules = React.memo( ({ createPrePackagedRules, - hasNoPermissions, + hasPermissions, loading, loadingCreatePrePackagedRules, refetchPrePackagedRulesStatus, @@ -110,7 +110,7 @@ export const AllRules = React.memo( formatUrl={formatUrl} selectedTab={allRulesTab} createPrePackagedRules={createPrePackagedRules} - hasNoPermissions={hasNoPermissions} + hasPermissions={hasPermissions} loading={loading} loadingCreatePrePackagedRules={loadingCreatePrePackagedRules} refetchPrePackagedRulesStatus={refetchPrePackagedRulesStatus} @@ -125,7 +125,7 @@ export const AllRules = React.memo( )} diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx index 353cc657f21167..8fd82a495e52f8 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx @@ -15,7 +15,6 @@ import { EuiWindowEvent, } from '@elastic/eui'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import uuid from 'uuid'; import { debounce } from 'lodash/fp'; import { History } from 'history'; @@ -25,7 +24,6 @@ import { CreatePreBuiltRules, FilterOptions, Rule, - exportRules, RulesSortingFields, } from '../../../../containers/detection_engine/rules'; @@ -36,7 +34,6 @@ import { useStateToaster } from '../../../../../common/components/toasters'; import { Loader } from '../../../../../common/components/loader'; import { Panel } from '../../../../../common/components/panel'; import { PrePackagedRulesPrompt } from '../../../../components/rules/pre_packaged_rules/load_empty_prompt'; -import { GenericDownloader } from '../../../../../common/components/generic_downloader'; import { AllRulesTables, SortingType } from '../../../../components/rules/all_rules_tables'; import { getPrePackagedRuleStatus } from '../helpers'; import * as i18n from '../translations'; @@ -53,6 +50,10 @@ import { AllRulesUtilityBar } from './utility_bar'; import { LastUpdatedAt } from '../../../../../common/components/last_updated'; import { DEFAULT_RULES_TABLE_REFRESH_SETTING } from '../../../../../../common/constants'; import { AllRulesTabs } from '.'; +import { useValueChanged } from '../../../../../common/hooks/use_value_changed'; +import { convertRulesFilterToKQL } from '../../../../containers/detection_engine/rules/utils'; +import { useBoolState } from '../../../../../common/hooks/use_bool_state'; +import { useAsyncConfirmation } from '../../../../containers/detection_engine/rules/rules_table/use_async_confirmation'; const INITIAL_SORT_FIELD = 'enabled'; @@ -60,7 +61,7 @@ interface RulesTableProps { history: History; formatUrl: FormatUrl; createPrePackagedRules: CreatePreBuiltRules | null; - hasNoPermissions: boolean; + hasPermissions: boolean; loading: boolean; loadingCreatePrePackagedRules: boolean; refetchPrePackagedRulesStatus: () => Promise; @@ -85,7 +86,7 @@ export const RulesTables = React.memo( history, formatUrl, createPrePackagedRules, - hasNoPermissions, + hasPermissions, loading, loadingCreatePrePackagedRules, refetchPrePackagedRulesStatus, @@ -115,14 +116,12 @@ export const RulesTables = React.memo( }>(DEFAULT_RULES_TABLE_REFRESH_SETTING); const rulesTable = useRulesTable({ - tableRef, initialStateOverride: { isRefreshOn: defaultAutoRefreshSetting.on, }, }); const { - exportRuleIds, filterOptions, loadingRuleIds, loadingRulesAction, @@ -133,12 +132,12 @@ export const RulesTables = React.memo( showIdleModal, isRefreshOn, isRefreshing, + isAllSelected, } = rulesTable.state; const { dispatch, updateOptions, - actionStopped, setShowIdleModal, setLastRefreshDate, setAutoRefreshOn, @@ -186,9 +185,24 @@ export const RulesTables = React.memo( actions, ]); + const [ + isDeleteConfirmationVisible, + showDeleteConfirmation, + hideDeleteConfirmation, + ] = useBoolState(); + + const [confirmDeletion, handleDeletionConfirm, handleDeletionCancel] = useAsyncConfirmation({ + onInit: showDeleteConfirmation, + onFinish: hideDeleteConfirmation, + }); + + const selectedItemsCount = isAllSelected ? pagination.total : selectedRuleIds.length; + const hasPagination = pagination.total > pagination.perPage; + const getBatchItemsPopoverContent = useCallback( (closePopover: () => void): JSX.Element[] => { return getBatchItems({ + isAllSelected, closePopover, dispatch, dispatchToaster, @@ -199,9 +213,13 @@ export const RulesTables = React.memo( reFetchRules, refetchPrePackagedRulesStatus, rules, + filterQuery: convertRulesFilterToKQL(filterOptions), + confirmDeletion, + selectedItemsCount, }); }, [ + isAllSelected, dispatch, dispatchToaster, hasMlPermissions, @@ -211,6 +229,9 @@ export const RulesTables = React.memo( rules, selectedRuleIds, hasActionsPrivileges, + filterOptions, + confirmDeletion, + selectedItemsCount, ] ); @@ -219,7 +240,7 @@ export const RulesTables = React.memo( pageIndex: pagination.page - 1, pageSize: pagination.perPage, totalItemCount: pagination.total, - pageSizeOptions: [5, 10, 20, 50, 100, 200, 300, 400, 500, 600], + pageSizeOptions: [5, 10, 20, 50, 100], }), [pagination] ); @@ -252,7 +273,7 @@ export const RulesTables = React.memo( formatUrl, history, hasMlPermissions, - hasNoPermissions, + hasPermissions, loadingRuleIds: loadingRulesAction != null && (loadingRulesAction === 'enable' || loadingRulesAction === 'disable') @@ -268,7 +289,7 @@ export const RulesTables = React.memo( formatUrl, refetchPrePackagedRulesStatus, hasActionsPrivileges, - hasNoPermissions, + hasPermissions, hasMlPermissions, history, loadingRuleIds, @@ -299,15 +320,43 @@ export const RulesTables = React.memo( } }, [createPrePackagedRules, reFetchRules, refetchPrePackagedRulesStatus]); + const isSelectAllCalled = useRef(false); + + // Synchronize selectedRuleIds with EuiBasicTable's selected rows + useValueChanged((ruleIds) => { + if (tableRef.current?.changeSelection != null) { + tableRef.current.setSelection(rules.filter((rule) => ruleIds.includes(rule.id))); + } + }, selectedRuleIds); + const euiBasicTableSelectionProps = useMemo( () => ({ selectable: (item: Rule) => !loadingRuleIds.includes(item.id), - onSelectionChange: (selected: Rule[]) => - dispatch({ type: 'selectedRuleIds', ids: selected.map((r) => r.id) }), + onSelectionChange: (selected: Rule[]) => { + /** + * EuiBasicTable doesn't provide declarative API to control selected rows. + * This limitation requires us to synchronize selection state manually using setSelection(). + * But it creates a chain reaction when the user clicks Select All: + * selectAll() -> setSelection() -> onSelectionChange() -> setSelection(). + * To break the chain we should check whether the onSelectionChange was triggered + * by the Select All action or not. + * + */ + if (isSelectAllCalled.current) { + isSelectAllCalled.current = false; + } else { + dispatch({ type: 'selectedRuleIds', ids: selected.map(({ id }) => id) }); + } + }, }), [loadingRuleIds, dispatch] ); + const toggleSelectAll = useCallback(() => { + isSelectAllCalled.current = true; + dispatch({ type: 'setIsAllSelected', isAllSelected: !isAllSelected }); + }, [dispatch, isAllSelected]); + const refreshTable = useCallback( async (mode: 'auto' | 'manual' = 'manual'): Promise => { if (isLoadingAnActionOnRule) { @@ -397,22 +446,6 @@ export const RulesTables = React.memo( [initLoading, prePackagedRuleStatus, rulesCustomInstalled] ); - const handleGenericDownloaderSuccess = useCallback( - (exportCount) => { - actionStopped(); - dispatchToaster({ - type: 'addToaster', - toast: { - id: uuid.v4(), - title: i18n.SUCCESSFULLY_EXPORTED_RULES(exportCount), - color: 'success', - iconType: 'check', - }, - }); - }, - [actionStopped, dispatchToaster] - ); - return ( <> @@ -421,13 +454,6 @@ export const RulesTables = React.memo( - - ( )} {initLoading && ( @@ -492,22 +518,39 @@ export const RulesTables = React.memo(

{i18n.REFRESH_PROMPT_BODY}

)} + {isDeleteConfirmationVisible && ( + +

{i18n.DELETE_CONFIRMATION_BODY}

+
+ )} {shouldShowRulesTable && ( <> { const wrapper = mount( { const wrapper = mount( { const wrapper = mount( { const wrapper = mount( { const wrapper = mount( { const wrapper = mount( void; + numberSelectedItems: number; onGetBatchItemsPopoverContent?: (closePopover: () => void) => JSX.Element[]; + onRefresh?: (refreshRule: boolean) => void; onRefreshSwitch?: (checked: boolean) => void; + onToggleSelectAll?: () => void; + paginationTotal: number; + showBulkActions: boolean; + hasPagination?: boolean; } export const AllRulesUtilityBar = React.memo( ({ - userHasNoPermissions, - onRefresh, - paginationTotal, + canBulkEdit, + isAllSelected, + isAutoRefreshOn, numberSelectedItems, onGetBatchItemsPopoverContent, - isAutoRefreshOn, - showBulkActions = true, + onRefresh, onRefreshSwitch, + onToggleSelectAll, + paginationTotal, + showBulkActions = true, + hasPagination, }) => { const handleGetBatchItemsPopoverContent = useCallback( (closePopover: () => void): JSX.Element | null => { @@ -99,7 +105,19 @@ export const AllRulesUtilityBar = React.memo( {i18n.SELECTED_RULES(numberSelectedItems)} - {!userHasNoPermissions && ( + + {canBulkEdit && onToggleSelectAll && hasPagination && ( + + {isAllSelected ? i18n.CLEAR_SELECTION : i18n.SELECT_ALL_RULES(paginationTotal)} + + )} + + {canBulkEdit && ( { ) { history.replace(getDetectionEngineUrl()); return null; - } else if (userHasNoPermissions(canUserCRUD)) { + } else if (!userHasPermissions(canUserCRUD)) { history.replace(getRulesUrl()); return null; } diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx index 8dac9e03514d1c..6727db8aba3b40 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx @@ -70,7 +70,7 @@ import { } from '../../../../components/alerts_table/default_config'; import { RuleSwitch } from '../../../../components/rules/rule_switch'; import { StepPanel } from '../../../../components/rules/step_panel'; -import { getStepsData, redirectToDetections, userHasNoPermissions } from '../helpers'; +import { getStepsData, redirectToDetections, userHasPermissions } from '../helpers'; import { useGlobalTime } from '../../../../../common/containers/use_global_time'; import { alertsHistogramOptions } from '../../../../components/alerts_histogram_panel/config'; import { inputsSelectors } from '../../../../../common/store/inputs'; @@ -461,7 +461,7 @@ const RuleDetailsPageComponent = () => { {ruleI18n.EDIT_RULE_SETTINGS} @@ -608,7 +608,7 @@ const RuleDetailsPageComponent = () => { isDisabled={ !isExistingRule || !canEditRuleWithActions(rule, hasActionsPrivileges) || - userHasNoPermissions(canUserCRUD) || + !userHasPermissions(canUserCRUD) || (!hasMlPermissions && !rule?.enabled) } enabled={isExistingRule && (rule?.enabled ?? false)} @@ -625,9 +625,7 @@ const RuleDetailsPageComponent = () => { { ) { history.replace(getDetectionEngineUrl()); return null; - } else if (userHasNoPermissions(canUserCRUD)) { + } else if (!userHasPermissions(canUserCRUD)) { history.replace(getRuleDetailsUrl(ruleId ?? '')); return null; } diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx index 4c3e5b18d4c1b9..fa600d9ce4a0e8 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx @@ -18,7 +18,7 @@ import { getPrePackagedRuleStatus, getPrePackagedTimelineStatus, determineDetailsValue, - userHasNoPermissions, + userHasPermissions, fillEmptySeverityMappings, } from './helpers'; import { mockRuleWithEverything, mockRule } from './all/__mocks__/mock'; @@ -403,26 +403,26 @@ describe('rule helpers', () => { }); }); - describe('userHasNoPermissions', () => { - test("returns false when user's CRUD operations are null", () => { - const result: boolean = userHasNoPermissions(null); - const userHasNoPermissionsExpectedResult = false; + describe('userHasPermissions', () => { + test("returns true when user's CRUD operations are null", () => { + const result: boolean = userHasPermissions(null); + const userHasPermissionsExpectedResult = true; - expect(result).toEqual(userHasNoPermissionsExpectedResult); + expect(result).toEqual(userHasPermissionsExpectedResult); }); - test('returns true when user cannot CRUD', () => { - const result: boolean = userHasNoPermissions(false); - const userHasNoPermissionsExpectedResult = true; + test('returns false when user cannot CRUD', () => { + const result: boolean = userHasPermissions(false); + const userHasPermissionsExpectedResult = false; - expect(result).toEqual(userHasNoPermissionsExpectedResult); + expect(result).toEqual(userHasPermissionsExpectedResult); }); - test('returns false when user can CRUD', () => { - const result: boolean = userHasNoPermissions(true); - const userHasNoPermissionsExpectedResult = false; + test('returns true when user can CRUD', () => { + const result: boolean = userHasPermissions(true); + const userHasPermissionsExpectedResult = true; - expect(result).toEqual(userHasNoPermissionsExpectedResult); + expect(result).toEqual(userHasPermissionsExpectedResult); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx index a88ff9bb2c9210..f20ace09ed2b61 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx @@ -405,8 +405,8 @@ export const getActionMessageParams = memoizeOne( ); // typed as null not undefined as the initial state for this value is null. -export const userHasNoPermissions = (canUserCRUD: boolean | null): boolean => - canUserCRUD != null ? !canUserCRUD : false; +export const userHasPermissions = (canUserCRUD: boolean | null): boolean => + canUserCRUD != null ? canUserCRUD : true; export const MaxWidthEuiFlexItem = styled(EuiFlexItem)` max-width: 1000px; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx index 8aca1cb960c1d2..8bacb10444a7d0 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx @@ -28,7 +28,7 @@ import { getPrePackagedRuleStatus, getPrePackagedTimelineStatus, redirectToDetections, - userHasNoPermissions, + userHasPermissions, } from './helpers'; import * as i18n from './translations'; import { SecurityPageName } from '../../../../app/types'; @@ -131,7 +131,7 @@ const RulesPageComponent: React.FC = () => { const loadPrebuiltRulesAndTemplatesButton = useMemo( () => getLoadPrebuiltRulesAndTemplatesButton({ - isDisabled: userHasNoPermissions(canUserCRUD) || loading, + isDisabled: !userHasPermissions(canUserCRUD) || loading, onClick: handleCreatePrePackagedRules, }), [canUserCRUD, getLoadPrebuiltRulesAndTemplatesButton, handleCreatePrePackagedRules, loading] @@ -140,7 +140,7 @@ const RulesPageComponent: React.FC = () => { const reloadPrebuiltRulesAndTemplatesButton = useMemo( () => getReloadPrebuiltRulesAndTemplatesButton({ - isDisabled: userHasNoPermissions(canUserCRUD) || loading, + isDisabled: !userHasPermissions(canUserCRUD) || loading, onClick: handleCreatePrePackagedRules, }), [canUserCRUD, getReloadPrebuiltRulesAndTemplatesButton, handleCreatePrePackagedRules, loading] @@ -213,7 +213,7 @@ const RulesPageComponent: React.FC = () => { { setShowImportModal(true); }} @@ -228,7 +228,7 @@ const RulesPageComponent: React.FC = () => { onClick={goToNewRule} href={formatUrl(getCreateRuleUrl())} iconType="plusInCircle" - isDisabled={userHasNoPermissions(canUserCRUD) || loading} + isDisabled={!userHasPermissions(canUserCRUD) || loading} > {i18n.ADD_NEW_RULE} @@ -250,7 +250,7 @@ const RulesPageComponent: React.FC = () => { data-test-subj="all-rules" loading={loading || prePackagedRuleLoading} loadingCreatePrePackagedRules={loadingCreatePrePackagedRules} - hasNoPermissions={userHasNoPermissions(canUserCRUD)} + hasPermissions={userHasPermissions(canUserCRUD)} refetchPrePackagedRulesStatus={handleRefetchPrePackagedRulesStatus} rulesCustomInstalled={rulesCustomInstalled} rulesInstalled={rulesInstalled} diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts index 1bfa62e9b77c05..defd976a04c4b6 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts @@ -165,13 +165,13 @@ export const EXPORT_FILENAME = i18n.translate( } ); -export const SUCCESSFULLY_EXPORTED_RULES = (totalRules: number) => +export const SUCCESSFULLY_EXPORTED_RULES = (exportedRules: number, totalRules: number) => i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.allRules.successfullyExportedRulesTitle', + 'xpack.securitySolution.detectionEngine.rules.allRules.successfullyExportedXofYRulesTitle', { - values: { totalRules }, + values: { totalRules, exportedRules }, defaultMessage: - 'Successfully exported {totalRules, plural, =0 {all rules} =1 {{totalRules} rule} other {{totalRules} rules}}', + 'Successfully exported {exportedRules} of {totalRules} {totalRules, plural, =1 {rule} other {rules}}. Prebuilt rules were excluded from the resulting file.', } ); @@ -202,6 +202,19 @@ export const SHOWING_RULES = (totalRules: number) => defaultMessage: 'Showing {totalRules} {totalRules, plural, =1 {rule} other {rules}}', }); +export const SELECT_ALL_RULES = (totalRules: number) => + i18n.translate('xpack.securitySolution.detectionEngine.rules.allRules.selectAllRulesTitle', { + values: { totalRules }, + defaultMessage: 'Select all {totalRules} {totalRules, plural, =1 {rule} other {rules}}', + }); + +export const CLEAR_SELECTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.clearSelectionTitle', + { + defaultMessage: 'Clear selection', + } +); + export const SELECTED_RULES = (selectedRules: number) => i18n.translate('xpack.securitySolution.detectionEngine.rules.allRules.selectedRulesTitle', { values: { selectedRules }, @@ -253,6 +266,13 @@ export const DUPLICATE_RULE_ERROR = i18n.translate( } ); +export const BULK_ACTION_FAILED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.actions.bulkActionFailedDescription', + { + defaultMessage: 'Failed to execte bulk action', + } +); + export const EXPORT_RULE = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.allRules.actions.exportRuleDescription', { @@ -577,6 +597,35 @@ export const REFRESH_PROMPT_BODY = i18n.translate( } ); +export const DELETE_CONFIRMATION_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.components.allRules.deleteConfirmationTitle', + { + defaultMessage: 'Confirm bulk deletion', + } +); + +export const DELETE_CONFIRMATION_CONFIRM = i18n.translate( + 'xpack.securitySolution.detectionEngine.components.allRules.deleteConfirmationConfirm', + { + defaultMessage: 'Confirm', + } +); + +export const DELETE_CONFIRMATION_CANCEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.components.allRules.deleteConfirmationCancel', + { + defaultMessage: 'Cancel', + } +); + +export const DELETE_CONFIRMATION_BODY = i18n.translate( + 'xpack.securitySolution.detectionEngine.components.allRules.deleteConfirmationBody', + { + defaultMessage: + 'This action will delete all rules that match current filter query. Click "Confirm" to continue.', + } +); + export const REFRESH_RULE_POPOVER_DESCRIPTION = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.refreshRulePopoverDescription', { diff --git a/x-pack/plugins/security_solution/public/management/components/back_to_external_app_button/back_to_external_app_button.tsx b/x-pack/plugins/security_solution/public/management/components/back_to_external_app_button/back_to_external_app_button.tsx new file mode 100644 index 00000000000000..78c854d9335840 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/back_to_external_app_button/back_to_external_app_button.tsx @@ -0,0 +1,52 @@ +/* + * 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 React, { memo } from 'react'; + +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiButtonEmpty } from '@elastic/eui'; +import styled from 'styled-components'; + +import { ListPageRouteState } from '../../../../common/endpoint/types'; + +import { useNavigateToAppEventHandler } from '../../../common/hooks/endpoint/use_navigate_to_app_event_handler'; + +const EuiButtonEmptyStyled = styled(EuiButtonEmpty)` + margin-bottom: ${({ theme }) => theme.eui.euiSizeS}; + + .euiIcon { + width: ${({ theme }) => theme.eui.euiIconSizes.small}; + height: ${({ theme }) => theme.eui.euiIconSizes.small}; + } + + .text { + font-size: ${({ theme }) => theme.eui.euiFontSizeXS}; + } +`; + +export const BackToExternalAppButton = memo( + ({ backButtonLabel, backButtonUrl, onBackButtonNavigateTo }) => { + const handleBackOnClick = useNavigateToAppEventHandler(...onBackButtonNavigateTo!); + + return ( + + {backButtonLabel || ( + + )} + + ); + } +); + +BackToExternalAppButton.displayName = 'BackToExternalAppButton'; diff --git a/x-pack/plugins/security_solution/public/common/components/generic_downloader/translations.ts b/x-pack/plugins/security_solution/public/management/components/back_to_external_app_button/index.ts similarity index 51% rename from x-pack/plugins/security_solution/public/common/components/generic_downloader/translations.ts rename to x-pack/plugins/security_solution/public/management/components/back_to_external_app_button/index.ts index 9104d4e7c0b453..d4a2f8de135466 100644 --- a/x-pack/plugins/security_solution/public/common/components/generic_downloader/translations.ts +++ b/x-pack/plugins/security_solution/public/management/components/back_to_external_app_button/index.ts @@ -5,11 +5,4 @@ * 2.0. */ -import { i18n } from '@kbn/i18n'; - -export const EXPORT_FAILURE = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.components.genericDownloader.exportFailureTitle', - { - defaultMessage: 'Failed to export data…', - } -); +export { BackToExternalAppButton } from './back_to_external_app_button'; diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.test.tsx index 5ee4c4eb0aacb1..6a106b14886772 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.test.tsx @@ -70,7 +70,7 @@ describe('Event filter flyout', () => { it('should renders correctly', () => { const component = render(); expect(component.getAllByText('Add Endpoint Event Filter')).not.toBeNull(); - expect(component.getByText('cancel')).not.toBeNull(); + expect(component.getByText('Cancel')).not.toBeNull(); expect(component.getByText('Endpoint Security')).not.toBeNull(); }); @@ -136,7 +136,7 @@ describe('Event filter flyout', () => { it('should close when click on cancel button', () => { const component = render(); - const cancelButton = component.getByText('cancel'); + const cancelButton = component.getByText('Cancel'); expect(onCancelMock).toHaveBeenCalledTimes(0); act(() => { @@ -170,7 +170,7 @@ describe('Event filter flyout', () => { }); }); - const cancelButton = component.getByText('cancel'); + const cancelButton = component.getByText('Cancel'); expect(onCancelMock).toHaveBeenCalledTimes(0); act(() => { @@ -184,7 +184,7 @@ describe('Event filter flyout', () => { const component = render({ id: 'fakeId', type: 'edit' }); expect(component.getAllByText('Update Endpoint Event Filter')).not.toBeNull(); - expect(component.getByText('cancel')).not.toBeNull(); + expect(component.getByText('Cancel')).not.toBeNull(); expect(component.getByText('Endpoint Security')).not.toBeNull(); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.tsx index c36e711879b8ed..1217488a75ea61 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.tsx @@ -141,7 +141,7 @@ export const EventFiltersFlyout: React.FC = memo(
diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx index 0867d0542e4c18..4171441e7de254 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx @@ -82,7 +82,16 @@ describe('Event filter form', () => { component = renderComponentWithdata(); expect(component.getByTestId('alert-exception-builder')).not.toBeNull(); - expect(component.getByText(NAME_ERROR)).not.toBeNull(); + }); + + it('should display name error only when on blur and empty name', () => { + component = renderComponentWithdata(); + expect(component.queryByText(NAME_ERROR)).toBeNull(); + const nameInput = component.getByPlaceholderText(NAME_PLACEHOLDER); + act(() => { + fireEvent.blur(nameInput); + }); + expect(component.queryByText(NAME_ERROR)).not.toBeNull(); }); it('should change name', async () => { @@ -102,6 +111,23 @@ describe('Event filter form', () => { expect(store.getState()!.management!.eventFilters!.form!.hasNameError).toBeFalsy(); }); + it('should change name with a white space still shows an error', async () => { + component = renderComponentWithdata(); + + const nameInput = component.getByPlaceholderText(NAME_PLACEHOLDER); + + act(() => { + fireEvent.change(nameInput, { + target: { + value: ' ', + }, + }); + }); + + expect(store.getState()!.management!.eventFilters!.form!.entry!.name).toBe(''); + expect(store.getState()!.management!.eventFilters!.form!.hasNameError).toBeTruthy(); + }); + it('should change comments', async () => { component = renderComponentWithdata(); diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.tsx index 83fd6ff1a366dc..121808b62f570d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { memo, useMemo, useCallback } from 'react'; +import React, { memo, useMemo, useCallback, useState } from 'react'; import { useDispatch } from 'react-redux'; import { Dispatch } from 'redux'; import { @@ -58,6 +58,7 @@ export const EventFiltersForm: React.FC = memo( const exception = useEventFiltersSelector(getFormEntryStateMutable); const hasNameError = useEventFiltersSelector(getHasNameError); const newComment = useEventFiltersSelector(getNewComment); + const [hasBeenInputNameVisited, setHasBeenInputNameVisited] = useState(false); // This value has to be memoized to avoid infinite useEffect loop on useFetchIndex const indexNames = useMemo(() => ['logs-endpoint.events.*'], []); @@ -90,11 +91,12 @@ export const EventFiltersForm: React.FC = memo( const handleOnChangeName = useCallback( (e: React.ChangeEvent) => { if (!exception) return; + const name = e.target.value.toString().trim(); dispatch({ type: 'eventFiltersChangeForm', payload: { - entry: { ...exception, name: e.target.value.toString() }, - hasNameError: !e.target.value, + entry: { ...exception, name }, + hasNameError: !name, }, }); }, @@ -140,7 +142,12 @@ export const EventFiltersForm: React.FC = memo( const nameInputMemo = useMemo( () => ( - + = memo( onChange={handleOnChangeName} fullWidth aria-label={NAME_PLACEHOLDER} - required + required={hasBeenInputNameVisited} maxLength={256} + onBlur={() => !hasBeenInputNameVisited && setHasBeenInputNameVisited(true)} /> ), - [hasNameError, exception?.name, handleOnChangeName] + [hasNameError, exception?.name, handleOnChangeName, hasBeenInputNameVisited] ); const osInputMemo = useMemo( diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/translations.ts b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/translations.ts index 086f2298d2c1af..7391251a936e62 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/translations.ts +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/translations.ts @@ -17,12 +17,12 @@ export const FORM_DESCRIPTION = i18n.translate( export const NAME_PLACEHOLDER = i18n.translate( 'xpack.securitySolution.eventFilter.form.name.placeholder', { - defaultMessage: 'Event exception name', + defaultMessage: 'Event filter name', } ); export const NAME_LABEL = i18n.translate('xpack.securitySolution.eventFilter.form.name.label', { - defaultMessage: 'Name your event exception', + defaultMessage: 'Name your event filter', }); export const NAME_ERROR = i18n.translate('xpack.securitySolution.eventFilter.form.name.error', { diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/modal/translations.ts b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/modal/translations.ts index 982d9b3bb12b32..66e0dfde298b87 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/modal/translations.ts +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/modal/translations.ts @@ -25,6 +25,6 @@ export const ACTIONS_CONFIRM = i18n.translate( export const ACTIONS_CANCEL = i18n.translate( 'xpack.securitySolution.eventFilter.modal.actions.cancel', { - defaultMessage: 'cancel', + defaultMessage: 'Cancel', } ); diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx index 465f92dfda767f..59d409874c5615 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx @@ -175,4 +175,30 @@ describe('When on the Event Filters List Page', () => { }); }); }); + + describe('and the back button is present', () => { + beforeEach(async () => { + renderResult = render(); + act(() => { + history.push('/event_filters', { + onBackButtonNavigateTo: [{ appId: 'appId' }], + backButtonLabel: 'back to fleet', + backButtonUrl: '/fleet', + }); + }); + }); + + it('back button is present', () => { + const button = renderResult.queryByTestId('backToOrigin'); + expect(button).not.toBeNull(); + expect(button).toHaveAttribute('href', '/fleet'); + }); + + it('back button is not present', () => { + act(() => { + history.push('/event_filters'); + }); + expect(renderResult.queryByTestId('backToOrigin')).toBeNull(); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx index 32fc0182104180..00ee80c5d70223 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx @@ -5,10 +5,10 @@ * 2.0. */ -import React, { memo, useCallback, useEffect } from 'react'; +import React, { memo, useCallback, useMemo, useEffect } from 'react'; import { useDispatch } from 'react-redux'; import { Dispatch } from 'redux'; -import { useHistory } from 'react-router-dom'; +import { useHistory, useLocation } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiButton, EuiSpacer, EuiHorizontalRule, EuiText } from '@elastic/eui'; @@ -34,7 +34,7 @@ import { showDeleteModal, } from '../store/selector'; import { PaginatedContent, PaginatedContentProps } from '../../../components/paginated_content'; -import { Immutable } from '../../../../../common/endpoint/types'; +import { Immutable, ListPageRouteState } from '../../../../../common/endpoint/types'; import { ExceptionItem, ExceptionItemProps, @@ -42,6 +42,7 @@ import { import { EventFilterDeleteModal } from './components/event_filter_delete_modal'; import { SearchBar } from '../../../components/search_bar'; +import { BackToExternalAppButton } from '../../../components/back_to_external_app_button'; type EventListPaginatedContent = PaginatedContentProps< Immutable, @@ -59,6 +60,7 @@ const AdministrationListPage = styled(_AdministrationListPage)` `; export const EventFiltersListPage = memo(() => { + const { state: routeState } = useLocation(); const history = useHistory(); const dispatch = useDispatch>(); const isActionError = useEventFiltersSelector(getActionError); @@ -103,6 +105,13 @@ export const EventFiltersListPage = memo(() => { } }, [dispatch, formEntry, history, isActionError, location, navigateCallback]); + const backButton = useMemo(() => { + if (routeState && routeState.onBackButtonNavigateTo) { + return ; + } + return null; + }, [routeState]); + const handleAddButtonClick = useCallback( () => navigateCallback({ @@ -173,6 +182,7 @@ export const EventFiltersListPage = memo(() => { return ( ( }; }, [eventFiltersApi, toasts]); - const eventFiltersRouteState = useMemo(() => { + const eventFiltersRouteState = useMemo(() => { const fleetPackageCustomUrlPath = `#${pagePathGetters.integration_details_custom({ pkgkey })}`; return { backButtonLabel: i18n.translate( diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_trusted_apps_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_trusted_apps_card.tsx index b1464d23e00fbd..ed3ba10c1e62bb 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_trusted_apps_card.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_trusted_apps_card.tsx @@ -17,7 +17,7 @@ import { import { useKibana } from '../../../../../../../../../../../src/plugins/kibana_react/public'; import { getTrustedAppsListPath } from '../../../../../../common/routing'; import { - TrustedAppsListPageRouteState, + ListPageRouteState, GetExceptionSummaryResponse, } from '../../../../../../../../common/endpoint/types'; import { PLUGIN_ID as FLEET_PLUGIN_ID } from '../../../../../../../../../fleet/common'; @@ -67,7 +67,7 @@ export const FleetTrustedAppsCard = memo(( }, [toasts, trustedAppsApi]); const trustedAppsListUrlPath = getTrustedAppsListPath(); - const trustedAppRouteState = useMemo(() => { + const trustedAppRouteState = useMemo(() => { const fleetPackageCustomUrlPath = `#${pagePathGetters.integration_details_custom({ pkgkey })}`; return { backButtonLabel: i18n.translate( diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx index fac9fb1e5bf6e5..691601b69e3cd7 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx @@ -900,4 +900,34 @@ describe('When on the Trusted Apps Page', () => { }); }); }); + + describe('and the back button is present', () => { + let renderResult: ReturnType; + beforeEach(async () => { + renderResult = render(); + await act(async () => { + await waitForAction('trustedAppsListResourceStateChanged'); + }); + reactTestingLibrary.act(() => { + history.push('/trusted_apps', { + onBackButtonNavigateTo: [{ appId: 'appId' }], + backButtonLabel: 'back to fleet', + backButtonUrl: '/fleet', + }); + }); + }); + + it('back button is present', () => { + const button = renderResult.queryByTestId('backToOrigin'); + expect(button).not.toBeNull(); + expect(button).toHaveAttribute('href', '/fleet'); + }); + + it('back button is not present', () => { + reactTestingLibrary.act(() => { + history.push('/trusted_apps'); + }); + expect(renderResult.queryByTestId('backToOrigin')).toBeNull(); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx index 5603b8e2d61c90..4cd6ad62f3a35f 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx @@ -7,11 +7,9 @@ import React, { memo, useMemo } from 'react'; import { useLocation } from 'react-router-dom'; -import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiButton, - EuiButtonEmpty, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, @@ -35,14 +33,14 @@ import { TrustedAppsGrid } from './components/trusted_apps_grid'; import { TrustedAppsList } from './components/trusted_apps_list'; import { TrustedAppDeletionDialog } from './trusted_app_deletion_dialog'; import { TrustedAppsNotifications } from './trusted_apps_notifications'; -import { TrustedAppsListPageRouteState } from '../../../../../common/endpoint/types'; -import { useNavigateToAppEventHandler } from '../../../../common/hooks/endpoint/use_navigate_to_app_event_handler'; import { ABOUT_TRUSTED_APPS, SEARCH_TRUSTED_APP_PLACEHOLDER } from './translations'; import { EmptyState } from './components/empty_state'; import { SearchBar } from '../../../components/search_bar'; +import { BackToExternalAppButton } from '../../../components/back_to_external_app_button'; +import { ListPageRouteState } from '../../../../../common/endpoint/types'; export const TrustedAppsPage = memo(() => { - const { state: routeState } = useLocation(); + const { state: routeState } = useLocation(); const location = useTrustedAppsSelector(getCurrentLocation); const totalItemsCount = useTrustedAppsSelector(getListTotalItemsCount); const isCheckingIfEntriesExists = useTrustedAppsSelector(checkingIfEntriesExist); @@ -161,43 +159,3 @@ export const TrustedAppsPage = memo(() => { }); TrustedAppsPage.displayName = 'TrustedAppsPage'; - -const EuiButtonEmptyStyled = styled(EuiButtonEmpty)` - margin-bottom: ${({ theme }) => theme.eui.euiSizeS}; - - .euiIcon { - width: ${({ theme }) => theme.eui.euiIconSizes.small}; - height: ${({ theme }) => theme.eui.euiIconSizes.small}; - } - - .text { - font-size: ${({ theme }) => theme.eui.euiFontSizeXS}; - } -`; - -const BackToExternalAppButton = memo( - ({ backButtonLabel, backButtonUrl, onBackButtonNavigateTo }) => { - const handleBackOnClick = useNavigateToAppEventHandler(...onBackButtonNavigateTo!); - - return ( - - {backButtonLabel || ( - - )} - - ); - } -); - -BackToExternalAppButton.displayName = 'BackToExternalAppButton'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.test.tsx index a273ef1df97882..738d166fcb9a4a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.test.tsx @@ -10,14 +10,20 @@ import React from 'react'; import { TimelineDownloader } from './export_timeline'; import { mockSelectedTimeline } from './mocks'; import * as i18n from '../translations'; +import { downloadBlob } from '../../../../common/utils/download_blob'; import { ReactWrapper, mount } from 'enzyme'; import { waitFor } from '@testing-library/react'; import { useParams } from 'react-router-dom'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; +import { exportSelectedTimeline } from '../../../containers/api'; jest.mock('../../../../common/hooks/use_app_toasts'); +jest.mock('../../../../common/utils/download_blob'); +jest.mock('../../../containers/api', () => ({ + exportSelectedTimeline: jest.fn(), +})); jest.mock('.', () => { return { @@ -37,6 +43,7 @@ jest.mock('react-router-dom', () => { describe('TimelineDownloader', () => { const mockAddSuccess = jest.fn(); (useAppToasts as jest.Mock).mockReturnValue({ addSuccess: mockAddSuccess }); + (exportSelectedTimeline as jest.Mock).mockReturnValue(new Blob()); let wrapper: ReactWrapper; const exportedIds = ['baa20980-6301-11ea-9223-95b6d4dd806c']; @@ -56,14 +63,14 @@ describe('TimelineDownloader', () => { mockAddSuccess.mockClear(); }); - describe('should not render a downloader', () => { - test('Without exportedIds', () => { + describe('ExportTimeline', () => { + it('should not start download without exportedIds', () => { const testProps = { ...defaultTestProps, exportedIds: undefined, }; wrapper = mount(); - expect(wrapper.find('[data-test-subj="export-timeline-downloader"]').exists()).toBeFalsy(); + expect(downloadBlob).toHaveBeenCalledTimes(0); }); test('With isEnableDownloader is false', () => { @@ -72,18 +79,23 @@ describe('TimelineDownloader', () => { isEnableDownloader: false, }; wrapper = mount(); - expect(wrapper.find('[data-test-subj="export-timeline-downloader"]').exists()).toBeFalsy(); + expect(downloadBlob).toHaveBeenCalledTimes(0); }); }); - describe('should render a downloader', () => { - test('With selectedItems and exportedIds is given and isEnableDownloader is true', () => { + describe('should start download', () => { + test('With selectedItems and exportedIds is given and isEnableDownloader is true', async () => { const testProps = { ...defaultTestProps, selectedItems: mockSelectedTimeline, }; wrapper = mount(); - expect(wrapper.find('[data-test-subj="export-timeline-downloader"]').exists()).toBeTruthy(); + + await waitFor(() => { + wrapper.update(); + + expect(downloadBlob).toHaveBeenCalledTimes(1); + }); }); test('With correct toast message on success for exported timelines', async () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.tsx index b8b1c76ffd6d7a..10e6ea9ee085c7 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.tsx @@ -5,23 +5,20 @@ * 2.0. */ -import React, { useCallback } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { useParams } from 'react-router-dom'; -import { - GenericDownloader, - ExportSelectedData, -} from '../../../../common/components/generic_downloader'; import * as i18n from '../translations'; import { TimelineType } from '../../../../../common/types/timeline'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; +import { exportSelectedTimeline } from '../../../containers/api'; +import { downloadBlob } from '../../../../common/utils/download_blob'; const ExportTimeline: React.FC<{ exportedIds: string[] | undefined; - getExportedData: ExportSelectedData; isEnableDownloader: boolean; onComplete?: () => void; -}> = ({ onComplete, isEnableDownloader, exportedIds, getExportedData }) => { +}> = ({ onComplete, isEnableDownloader, exportedIds }) => { const { tabName: timelineType } = useParams<{ tabName: TimelineType }>(); const { addSuccess } = useAppToasts(); @@ -47,20 +44,28 @@ const ExportTimeline: React.FC<{ } }, [onComplete]); - return ( - <> - {exportedIds != null && isEnableDownloader && ( - - )} - - ); + useEffect(() => { + const downloadTimeline = async () => { + if (exportedIds?.length && isEnableDownloader) { + const result = await exportSelectedTimeline({ ids: exportedIds }); + if (result instanceof Blob) { + downloadBlob(result, `${i18n.EXPORT_FILENAME}.ndjson`); + onExportSuccess(exportedIds.length); + } else { + onExportFailure(); + } + } + }; + + downloadTimeline(); + // We probably don't need to have ExportTimeline in the form of a React component. + // See https://github.com/elastic/kibana/issues/101571 for more detail. + // But for now, it uses isEnableDownloader as a signal to start downloading. + // Other variables are excluded from the deps array to avoid false positives + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [exportedIds, isEnableDownloader]); + + return null; }; ExportTimeline.displayName = 'ExportTimeline'; export const TimelineDownloader = React.memo(ExportTimeline); diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/index.tsx index 250e7847edb5c8..aa447c9e84f97a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/index.tsx @@ -10,7 +10,6 @@ import { DeleteTimelines } from '../types'; import { TimelineDownloader } from './export_timeline'; import { DeleteTimelineModalOverlay } from '../delete_timeline_modal'; -import { exportSelectedTimeline } from '../../../containers/api'; export interface ExportTimeline { disableExportTimelineDownloader: () => void; @@ -37,7 +36,6 @@ export const EditTimelineActionsComponent: React.FC<{ @@ -55,4 +53,3 @@ export const EditTimelineActionsComponent: React.FC<{ ); export const EditTimelineActions = React.memo(EditTimelineActionsComponent); -export const EditOneTimelineAction = React.memo(EditTimelineActionsComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.tsx index 316b6cff766eab..922e40d6d860e4 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.tsx @@ -24,7 +24,7 @@ import { importTimelines } from '../../containers/api'; import { useEditTimelineBatchActions } from './edit_timeline_batch_actions'; import { useEditTimelineActions } from './edit_timeline_actions'; -import { EditOneTimelineAction } from './export_timeline'; +import { EditTimelineActions } from './export_timeline'; import { SearchRow } from './search_row'; import { TimelinesTable } from './timelines_table'; import * as i18n from './translations'; @@ -170,7 +170,7 @@ export const OpenTimeline = React.memo( return ( <> - => { +}: ExportDocumentsProps): Promise => { let requestBody; try { requestBody = ids.length > 0 ? JSON.stringify({ ids }) : undefined; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts index 857762dec45e94..3942d1637fedd1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -18,6 +18,7 @@ import { DETECTION_ENGINE_PREPACKAGED_URL, DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL, DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL, + DETECTION_ENGINE_RULES_BULK_ACTION, } from '../../../../../common/constants'; import { ShardsResponse } from '../../../types'; import { @@ -36,6 +37,7 @@ import { getSignalsMigrationStatusSchemaMock } from '../../../../../common/detec import { RuleParams } from '../../schemas/rule_schemas'; import { Alert } from '../../../../../../alerting/common'; import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; +import { getPerformBulkActionSchemaMock } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema.mock'; export const typicalSetStatusSignalByIdsPayload = (): SetSignalsStatusSchemaDecoded => ({ signal_ids: ['somefakeid1', 'somefakeid2'], @@ -107,6 +109,13 @@ export const getPatchBulkRequest = () => body: [getCreateRulesSchemaMock()], }); +export const getBulkActionRequest = () => + requestMock.create({ + method: 'patch', + path: DETECTION_ENGINE_RULES_BULK_ACTION, + body: getPerformBulkActionSchemaMock(), + }); + export const getDeleteBulkRequest = () => requestMock.create({ method: 'delete', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts index 1e7ba976d6915f..3068521682f8fd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts @@ -23,9 +23,8 @@ import { getIdBulkError } from './utils'; import { transformValidateBulkError } from './validate'; import { transformBulkError, buildSiemResponse, createBulkErrorObject } from '../utils'; import { deleteRules } from '../../rules/delete_rules'; -import { deleteNotifications } from '../../notifications/delete_notifications'; -import { deleteRuleActionsSavedObject } from '../../rule_actions/delete_rule_actions_saved_object'; import { ruleStatusSavedObjectsClientFactory } from '../../signals/rule_status_saved_objects_client'; +import { readRules } from '../../rules/read_rules'; type Config = RouteConfig; type Handler = RequestHandler< @@ -74,27 +73,24 @@ export const deleteRulesBulkRoute = (router: SecuritySolutionPluginRouter) => { } try { - const rule = await deleteRules({ - alertsClient, - id, - ruleId, - }); - if (rule != null) { - await deleteNotifications({ alertsClient, ruleAlertId: rule.id }); - await deleteRuleActionsSavedObject({ - ruleAlertId: rule.id, - savedObjectsClient, - }); - const ruleStatuses = await ruleStatusClient.find({ - perPage: 6, - search: rule.id, - searchFields: ['alertId'], - }); - ruleStatuses.saved_objects.forEach(async (obj) => ruleStatusClient.delete(obj.id)); - return transformValidateBulkError(idOrRuleIdOrUnknown, rule, undefined, ruleStatuses); - } else { + const rule = await readRules({ alertsClient, id, ruleId }); + if (!rule) { return getIdBulkError({ id, ruleId }); } + + const ruleStatuses = await ruleStatusClient.find({ + perPage: 6, + search: rule.id, + searchFields: ['alertId'], + }); + await deleteRules({ + alertsClient, + savedObjectsClient, + ruleStatusClient, + ruleStatuses, + id: rule.id, + }); + return transformValidateBulkError(idOrRuleIdOrUnknown, rule, undefined, ruleStatuses); } catch (err) { return transformBulkError(idOrRuleIdOrUnknown, err); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts index 4b05f603b85b7c..4a6b41230f799e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts @@ -19,9 +19,8 @@ import { deleteRules } from '../../rules/delete_rules'; import { getIdError, transform } from './utils'; import { buildSiemResponse } from '../utils'; -import { deleteNotifications } from '../../notifications/delete_notifications'; -import { deleteRuleActionsSavedObject } from '../../rule_actions/delete_rule_actions_saved_object'; import { ruleStatusSavedObjectsClientFactory } from '../../signals/rule_status_saved_objects_client'; +import { readRules } from '../../rules/read_rules'; export const deleteRulesRoute = ( router: SecuritySolutionPluginRouter, @@ -57,36 +56,33 @@ export const deleteRulesRoute = ( } const ruleStatusClient = ruleStatusSavedObjectsClientFactory(savedObjectsClient); - const rule = await deleteRules({ - alertsClient, - id, - ruleId, - }); - if (rule != null) { - await deleteNotifications({ alertsClient, ruleAlertId: rule.id }); - await deleteRuleActionsSavedObject({ - ruleAlertId: rule.id, - savedObjectsClient, - }); - const ruleStatuses = await ruleStatusClient.find({ - perPage: 6, - search: rule.id, - searchFields: ['alertId'], - }); - ruleStatuses.saved_objects.forEach(async (obj) => ruleStatusClient.delete(obj.id)); - const transformed = transform(rule, undefined, ruleStatuses.saved_objects[0]); - if (transformed == null) { - return siemResponse.error({ statusCode: 500, body: 'failed to transform alert' }); - } else { - return response.ok({ body: transformed ?? {} }); - } - } else { + const rule = await readRules({ alertsClient, id, ruleId }); + if (!rule) { const error = getIdError({ id, ruleId }); return siemResponse.error({ body: error.message, statusCode: error.statusCode, }); } + + const ruleStatuses = await ruleStatusClient.find({ + perPage: 6, + search: rule.id, + searchFields: ['alertId'], + }); + await deleteRules({ + alertsClient, + savedObjectsClient, + ruleStatusClient, + ruleStatuses, + id: rule.id, + }); + const transformed = transform(rule, undefined, ruleStatuses.saved_objects[0]); + if (transformed == null) { + return siemResponse.error({ statusCode: 500, body: 'failed to transform alert' }); + } else { + return response.ok({ body: transformed ?? {} }); + } } catch (err) { const error = transformError(err); return siemResponse.error({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts new file mode 100644 index 00000000000000..60677fd8eda90c --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts @@ -0,0 +1,148 @@ +/* + * 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 { DETECTION_ENGINE_RULES_BULK_ACTION } from '../../../../../common/constants'; +import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; +import { buildMlAuthz } from '../../../machine_learning/authz'; +import { + getEmptyFindResult, + getFindResultStatus, + getBulkActionRequest, + getFindResultWithSingleHit, + getFindResultWithMultiHits, +} from '../__mocks__/request_responses'; +import { requestContextMock, serverMock, requestMock } from '../__mocks__'; +import { performBulkActionRoute } from './perform_bulk_action_route'; +import { getPerformBulkActionSchemaMock } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema.mock'; + +jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); + +describe('perform_bulk_action', () => { + let server: ReturnType; + let { clients, context } = requestContextMock.createTools(); + let ml: ReturnType; + + beforeEach(() => { + server = serverMock.create(); + ({ clients, context } = requestContextMock.createTools()); + ml = mlServicesMock.createSetupContract(); + + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + + performBulkActionRoute(server.router, ml); + }); + + describe('status codes', () => { + it('returns 200 when performing bulk action with all dependencies present', async () => { + const response = await server.inject(getBulkActionRequest(), context); + expect(response.status).toEqual(200); + expect(response.body).toEqual({ success: true, rules_count: 1 }); + }); + + it("returns 200 when provided filter query doesn't match any rules", async () => { + clients.alertsClient.find.mockResolvedValue(getEmptyFindResult()); + const response = await server.inject(getBulkActionRequest(), context); + expect(response.status).toEqual(200); + expect(response.body).toEqual({ success: true, rules_count: 0 }); + }); + + it('returns 400 when provided filter query matches too many rules', async () => { + clients.alertsClient.find.mockResolvedValue( + getFindResultWithMultiHits({ data: [], total: Infinity }) + ); + const response = await server.inject(getBulkActionRequest(), context); + expect(response.status).toEqual(400); + expect(response.body).toEqual({ + message: 'More than 10000 rules matched the filter query. Try to narrow it down.', + status_code: 400, + }); + }); + + it('returns 404 if alertClient is not available on the route', async () => { + context.alerting!.getAlertsClient = jest.fn(); + const response = await server.inject(getBulkActionRequest(), context); + expect(response.status).toEqual(404); + expect(response.body).toEqual({ message: 'Not Found', status_code: 404 }); + }); + + it('catches error if disable throws error', async () => { + clients.alertsClient.disable.mockImplementation(async () => { + throw new Error('Test error'); + }); + const response = await server.inject(getBulkActionRequest(), context); + expect(response.status).toEqual(500); + expect(response.body).toEqual({ + message: 'Test error', + status_code: 500, + }); + }); + + it('rejects patching a rule if mlAuthz fails', async () => { + (buildMlAuthz as jest.Mock).mockReturnValueOnce({ + validateRuleType: jest + .fn() + .mockResolvedValue({ valid: false, message: 'mocked validation message' }), + }); + const response = await server.inject(getBulkActionRequest(), context); + + expect(response.status).toEqual(403); + expect(response.body).toEqual({ + message: 'mocked validation message', + status_code: 403, + }); + }); + }); + + describe('request validation', () => { + it('rejects payloads with no action', async () => { + const request = requestMock.create({ + method: 'patch', + path: DETECTION_ENGINE_RULES_BULK_ACTION, + body: { ...getPerformBulkActionSchemaMock(), action: undefined }, + }); + const result = server.validate(request); + expect(result.badRequest).toHaveBeenCalledWith( + 'Invalid value "undefined" supplied to "action"' + ); + }); + + it('rejects payloads with unknown action', async () => { + const request = requestMock.create({ + method: 'patch', + path: DETECTION_ENGINE_RULES_BULK_ACTION, + body: { ...getPerformBulkActionSchemaMock(), action: 'unknown' }, + }); + const result = server.validate(request); + expect(result.badRequest).toHaveBeenCalledWith( + 'Invalid value "unknown" supplied to "action"' + ); + }); + + it('accepts payloads with no query', async () => { + const request = requestMock.create({ + method: 'patch', + path: DETECTION_ENGINE_RULES_BULK_ACTION, + body: { ...getPerformBulkActionSchemaMock(), query: undefined }, + }); + const result = server.validate(request); + + expect(result.ok).toHaveBeenCalled(); + }); + + it('accepts payloads with query and action', async () => { + const request = requestMock.create({ + method: 'patch', + path: DETECTION_ENGINE_RULES_BULK_ACTION, + body: getPerformBulkActionSchemaMock(), + }); + const result = server.validate(request); + + expect(result.ok).toHaveBeenCalled(); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts new file mode 100644 index 00000000000000..9d569acf3782ae --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts @@ -0,0 +1,172 @@ +/* + * 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 { transformError } from '@kbn/securitysolution-es-utils'; +import { DETECTION_ENGINE_RULES_BULK_ACTION } from '../../../../../common/constants'; +import { BulkAction } from '../../../../../common/detection_engine/schemas/common/schemas'; +import { performBulkActionSchema } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { SetupPlugins } from '../../../../plugin'; +import type { SecuritySolutionPluginRouter } from '../../../../types'; +import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; +import { buildMlAuthz } from '../../../machine_learning/authz'; +import { throwHttpError } from '../../../machine_learning/validation'; +import { deleteRules } from '../../rules/delete_rules'; +import { duplicateRule } from '../../rules/duplicate_rule'; +import { enableRule } from '../../rules/enable_rule'; +import { findRules } from '../../rules/find_rules'; +import { getExportByObjectIds } from '../../rules/get_export_by_object_ids'; +import { updateRulesNotifications } from '../../rules/update_rules_notifications'; +import { getRuleActionsSavedObject } from '../../rule_actions/get_rule_actions_saved_object'; +import { ruleStatusSavedObjectsClientFactory } from '../../signals/rule_status_saved_objects_client'; +import { buildSiemResponse } from '../utils'; + +const BULK_ACTION_RULES_LIMIT = 10000; + +export const performBulkActionRoute = ( + router: SecuritySolutionPluginRouter, + ml: SetupPlugins['ml'] +) => { + router.post( + { + path: DETECTION_ENGINE_RULES_BULK_ACTION, + validate: { + body: buildRouteValidation(performBulkActionSchema), + }, + options: { + tags: ['access:securitySolution'], + }, + }, + async (context, request, response) => { + const { body } = request; + const siemResponse = buildSiemResponse(response); + + try { + const alertsClient = context.alerting?.getAlertsClient(); + const savedObjectsClient = context.core.savedObjects.client; + const ruleStatusClient = ruleStatusSavedObjectsClientFactory(savedObjectsClient); + + const mlAuthz = buildMlAuthz({ + license: context.licensing.license, + ml, + request, + savedObjectsClient, + }); + + if (!alertsClient) { + return siemResponse.error({ statusCode: 404 }); + } + + const rules = await findRules({ + alertsClient, + perPage: BULK_ACTION_RULES_LIMIT, + filter: body.query !== '' ? body.query : undefined, + page: undefined, + sortField: undefined, + sortOrder: undefined, + fields: undefined, + }); + + if (rules.total > BULK_ACTION_RULES_LIMIT) { + return siemResponse.error({ + body: `More than ${BULK_ACTION_RULES_LIMIT} rules matched the filter query. Try to narrow it down.`, + statusCode: 400, + }); + } + + switch (body.action) { + case BulkAction.enable: + await Promise.all( + rules.data.map(async (rule) => { + if (!rule.enabled) { + throwHttpError(await mlAuthz.validateRuleType(rule.params.type)); + await enableRule({ rule, alertsClient, savedObjectsClient }); + } + }) + ); + break; + case BulkAction.disable: + await Promise.all( + rules.data.map(async (rule) => { + if (rule.enabled) { + throwHttpError(await mlAuthz.validateRuleType(rule.params.type)); + await alertsClient.disable({ id: rule.id }); + } + }) + ); + break; + case BulkAction.delete: + await Promise.all( + rules.data.map(async (rule) => { + const ruleStatuses = await ruleStatusClient.find({ + perPage: 6, + search: rule.id, + searchFields: ['alertId'], + }); + await deleteRules({ + alertsClient, + savedObjectsClient, + ruleStatusClient, + ruleStatuses, + id: rule.id, + }); + }) + ); + break; + case BulkAction.duplicate: + await Promise.all( + rules.data.map(async (rule) => { + throwHttpError(await mlAuthz.validateRuleType(rule.params.type)); + + const createdRule = await alertsClient.create({ + data: duplicateRule(rule), + }); + + const ruleActions = await getRuleActionsSavedObject({ + savedObjectsClient, + ruleAlertId: rule.id, + }); + + await updateRulesNotifications({ + ruleAlertId: createdRule.id, + alertsClient, + savedObjectsClient, + enabled: createdRule.enabled, + actions: ruleActions?.actions || [], + throttle: ruleActions?.alertThrottle, + name: createdRule.name, + }); + }) + ); + break; + case BulkAction.export: + const exported = await getExportByObjectIds( + alertsClient, + rules.data.map(({ params }) => ({ rule_id: params.ruleId })) + ); + + const responseBody = `${exported.rulesNdjson}${exported.exportDetails}`; + + return response.ok({ + headers: { + 'Content-Disposition': `attachment; filename="rules_export.ndjson"`, + 'Content-Type': 'application/ndjson', + }, + body: responseBody, + }); + } + + return response.ok({ body: { success: true, rules_count: rules.data.length } }); + } catch (err) { + const error = transformError(err); + return siemResponse.error({ + body: error.message, + statusCode: error.statusCode, + }); + } + } + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.test.ts index 972e44c718f94e..a871c7157d5e83 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.test.ts @@ -33,8 +33,8 @@ describe('add_tags', () => { const tags2 = addTags(tags1, 'rule-1', false); expect(tags2).toEqual([ 'tag-1', - `${INTERNAL_RULE_ID_KEY}:rule-1`, `${INTERNAL_IMMUTABLE_KEY}:false`, + `${INTERNAL_RULE_ID_KEY}:rule-1`, ]); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.ts index 84a24839384210..6ff4a54ad8e544 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.ts @@ -10,7 +10,7 @@ import { INTERNAL_RULE_ID_KEY, INTERNAL_IMMUTABLE_KEY } from '../../../../common export const addTags = (tags: string[], ruleId: string, immutable: boolean): string[] => { return Array.from( new Set([ - ...tags, + ...tags.filter((tag) => !tag.startsWith(INTERNAL_RULE_ID_KEY)), `${INTERNAL_RULE_ID_KEY}:${ruleId}`, `${INTERNAL_IMMUTABLE_KEY}:${immutable}`, ]) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.test.ts index e7a4df790d62d2..f581be9e1f62b5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.test.ts @@ -5,138 +5,74 @@ * 2.0. */ +import { savedObjectsClientMock } from '../../../../../../../src/core/server/mocks'; import { alertsClientMock } from '../../../../../alerting/server/mocks'; +import { ruleStatusSavedObjectsClientMock } from '../signals/__mocks__/rule_status_saved_objects_client.mock'; import { deleteRules } from './delete_rules'; -import { readRules } from './read_rules'; -jest.mock('./read_rules'); +import { deleteNotifications } from '../notifications/delete_notifications'; +import { deleteRuleActionsSavedObject } from '../rule_actions/delete_rule_actions_saved_object'; +import { SavedObjectsFindResult } from '../../../../../../../src/core/server'; +import { IRuleStatusSOAttributes } from './types'; + +jest.mock('../notifications/delete_notifications'); +jest.mock('../rule_actions/delete_rule_actions_saved_object'); describe('deleteRules', () => { let alertsClient: ReturnType; - const notificationId = 'notification-52128c15-0d1b-4716-a4c5-46997ac7f3bd'; - const ruleId = 'rule-04128c15-0d1b-4716-a4c5-46997ac7f3bd'; + let ruleStatusClient: ReturnType; + let savedObjectsClient: ReturnType; beforeEach(() => { alertsClient = alertsClientMock.create(); + savedObjectsClient = savedObjectsClientMock.create(); + ruleStatusClient = ruleStatusSavedObjectsClientMock.create(); }); - it('should return null if notification was not found', async () => { - (readRules as jest.Mock).mockResolvedValue(null); - - const result = await deleteRules({ - alertsClient, - id: notificationId, - ruleId, - }); - - expect(result).toBe(null); - }); - - it('should call alertsClient.delete if notification was found', async () => { - (readRules as jest.Mock).mockResolvedValue({ - id: notificationId, - }); - - const result = await deleteRules({ - alertsClient, - id: notificationId, - ruleId, - }); - - expect(alertsClient.delete).toHaveBeenCalledWith( - expect.objectContaining({ - id: notificationId, - }) - ); - expect(result).toEqual({ id: notificationId }); - }); - - it('should call alertsClient.delete if ruleId was undefined', async () => { - (readRules as jest.Mock).mockResolvedValue({ - id: null, - }); - - const result = await deleteRules({ - alertsClient, - id: notificationId, - ruleId: undefined, - }); - - expect(alertsClient.delete).toHaveBeenCalledWith( - expect.objectContaining({ - id: notificationId, - }) - ); - expect(result).toEqual({ id: null }); - }); - - it('should return null if alertsClient.delete rejects with 404 if ruleId was undefined', async () => { - (readRules as jest.Mock).mockResolvedValue({ - id: null, - }); - - alertsClient.delete.mockRejectedValue({ - output: { - statusCode: 404, + it('should delete the rule along with its notifications, actions, and statuses', async () => { + const ruleStatus: SavedObjectsFindResult = { + id: 'statusId', + type: '', + references: [], + attributes: { + alertId: 'alertId', + statusDate: '', + lastFailureAt: null, + lastFailureMessage: null, + lastSuccessAt: null, + lastSuccessMessage: null, + status: null, + lastLookBackDate: null, + gap: null, + bulkCreateTimeDurations: null, + searchAfterTimeDurations: null, }, - }); + score: 0, + }; - const result = await deleteRules({ + const rule = { alertsClient, - id: notificationId, - ruleId: undefined, - }); - - expect(alertsClient.delete).toHaveBeenCalledWith( - expect.objectContaining({ - id: notificationId, - }) - ); - expect(result).toEqual(null); - }); - - it('should return error object if alertsClient.delete rejects with status different than 404 and if ruleId was undefined', async () => { - (readRules as jest.Mock).mockResolvedValue({ - id: null, - }); - - const errorObject = { - output: { - statusCode: 500, + savedObjectsClient, + ruleStatusClient, + id: 'ruleId', + ruleStatuses: { + total: 0, + per_page: 0, + page: 0, + saved_objects: [ruleStatus], }, }; - alertsClient.delete.mockRejectedValue(errorObject); + await deleteRules(rule); - let errorResult; - try { - await deleteRules({ - alertsClient, - id: notificationId, - ruleId: undefined, - }); - } catch (error) { - errorResult = error; - } - - expect(alertsClient.delete).toHaveBeenCalledWith( - expect.objectContaining({ - id: notificationId, - }) - ); - expect(errorResult).toEqual(errorObject); - }); - - it('should return null if ruleId and id was undefined', async () => { - (readRules as jest.Mock).mockResolvedValue({ - id: null, + expect(alertsClient.delete).toHaveBeenCalledWith({ id: rule.id }); + expect(deleteNotifications).toHaveBeenCalledWith({ + ruleAlertId: rule.id, + alertsClient: expect.any(Object), }); - - const result = await deleteRules({ - alertsClient, - id: undefined, - ruleId: undefined, + expect(deleteRuleActionsSavedObject).toHaveBeenCalledWith({ + ruleAlertId: rule.id, + savedObjectsClient: expect.any(Object), }); - - expect(result).toEqual(null); + expect(ruleStatusClient.delete).toHaveBeenCalledWith(ruleStatus.id); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.ts index 3947103e7625d8..ed5477599253bd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.ts @@ -5,30 +5,19 @@ * 2.0. */ -import { readRules } from './read_rules'; +import { deleteNotifications } from '../notifications/delete_notifications'; +import { deleteRuleActionsSavedObject } from '../rule_actions/delete_rule_actions_saved_object'; import { DeleteRuleOptions } from './types'; -export const deleteRules = async ({ alertsClient, id, ruleId }: DeleteRuleOptions) => { - const rule = await readRules({ alertsClient, id, ruleId }); - if (rule == null) { - return null; - } - - if (ruleId != null) { - await alertsClient.delete({ id: rule.id }); - return rule; - } else if (id != null) { - try { - await alertsClient.delete({ id }); - return rule; - } catch (err) { - if (err.output.statusCode === 404) { - return null; - } else { - throw err; - } - } - } else { - return null; - } +export const deleteRules = async ({ + alertsClient, + savedObjectsClient, + ruleStatusClient, + ruleStatuses, + id, +}: DeleteRuleOptions) => { + await alertsClient.delete({ id }); + await deleteNotifications({ alertsClient, ruleAlertId: id }); + await deleteRuleActionsSavedObject({ ruleAlertId: id, savedObjectsClient }); + ruleStatuses.saved_objects.forEach(async (obj) => ruleStatusClient.delete(obj.id)); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.test.ts new file mode 100644 index 00000000000000..3046999a632c62 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.test.ts @@ -0,0 +1,133 @@ +/* + * 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 uuid from 'uuid'; +import { INTERNAL_IMMUTABLE_KEY } from '../../../../common/constants'; +import { duplicateRule } from './duplicate_rule'; + +jest.mock('uuid', () => ({ + v4: jest.fn(), +})); + +describe('duplicateRule', () => { + it('should return a copy of rule with new ruleId', () => { + (uuid.v4 as jest.Mock).mockReturnValue('newId'); + + expect( + duplicateRule({ + id: 'oldTestRuleId', + notifyWhen: 'onActiveAlert', + name: 'test', + tags: ['test', '__internal_rule_id:oldTestRuleId', `${INTERNAL_IMMUTABLE_KEY}:false`], + alertTypeId: 'siem.signals', + consumer: 'siem', + params: { + savedId: undefined, + author: [], + description: 'test', + ruleId: 'oldTestRuleId', + falsePositives: [], + from: 'now-360s', + immutable: false, + license: '', + outputIndex: '.siem-signals-default', + meta: undefined, + maxSignals: 100, + riskScore: 42, + riskScoreMapping: [], + severity: 'low', + severityMapping: [], + threat: [], + to: 'now', + references: [], + version: 1, + exceptionsList: [], + type: 'query', + language: 'kuery', + index: [], + query: 'process.args : "chmod"', + filters: [], + buildingBlockType: undefined, + note: undefined, + timelineId: undefined, + timelineTitle: undefined, + ruleNameOverride: undefined, + timestampOverride: undefined, + }, + schedule: { + interval: '5m', + }, + enabled: false, + actions: [], + throttle: null, + apiKeyOwner: 'kibana', + createdBy: 'kibana', + updatedBy: 'kibana', + muteAll: false, + mutedInstanceIds: [], + updatedAt: new Date(2021, 0), + createdAt: new Date(2021, 0), + scheduledTaskId: undefined, + executionStatus: { + lastExecutionDate: new Date(2021, 0), + status: 'ok', + }, + }) + ).toMatchInlineSnapshot(` + Object { + "actions": Array [], + "alertTypeId": "siem.signals", + "consumer": "siem", + "enabled": false, + "name": "test [Duplicate]", + "notifyWhen": null, + "params": Object { + "author": Array [], + "buildingBlockType": undefined, + "description": "test", + "exceptionsList": Array [], + "falsePositives": Array [], + "filters": Array [], + "from": "now-360s", + "immutable": false, + "index": Array [], + "language": "kuery", + "license": "", + "maxSignals": 100, + "meta": undefined, + "note": undefined, + "outputIndex": ".siem-signals-default", + "query": "process.args : \\"chmod\\"", + "references": Array [], + "riskScore": 42, + "riskScoreMapping": Array [], + "ruleId": "newId", + "ruleNameOverride": undefined, + "savedId": undefined, + "severity": "low", + "severityMapping": Array [], + "threat": Array [], + "timelineId": undefined, + "timelineTitle": undefined, + "timestampOverride": undefined, + "to": "now", + "type": "query", + "version": 1, + }, + "schedule": Object { + "interval": "5m", + }, + "tags": Array [ + "test", + "__internal_immutable:false", + "__internal_rule_id:newId", + ], + "throttle": null, + } + `); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.ts new file mode 100644 index 00000000000000..2f12e335074227 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.ts @@ -0,0 +1,40 @@ +/* + * 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 uuid from 'uuid'; +import { i18n } from '@kbn/i18n'; +import { SanitizedAlert } from '../../../../../alerting/common'; +import { SERVER_APP_ID, SIGNALS_ID } from '../../../../common/constants'; +import { InternalRuleCreate, RuleParams } from '../schemas/rule_schemas'; +import { addTags } from './add_tags'; + +const DUPLICATE_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.cloneRule.duplicateTitle', + { + defaultMessage: 'Duplicate', + } +); + +export const duplicateRule = (rule: SanitizedAlert): InternalRuleCreate => { + const newRuleId = uuid.v4(); + return { + name: `${rule.name} [${DUPLICATE_TITLE}]`, + tags: addTags(rule.tags, newRuleId, false), + alertTypeId: SIGNALS_ID, + consumer: SERVER_APP_ID, + params: { + ...rule.params, + immutable: false, + ruleId: newRuleId, + }, + schedule: rule.schedule, + enabled: false, + actions: rule.actions, + throttle: null, + notifyWhen: null, + }; +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/enable_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/enable_rule.ts new file mode 100644 index 00000000000000..dc4cca2059b3e3 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/enable_rule.ts @@ -0,0 +1,47 @@ +/* + * 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 { SavedObjectsClientContract } from 'kibana/server'; +import { SanitizedAlert } from '../../../../../alerting/common'; +import { AlertsClient } from '../../../../../alerting/server'; +import { RuleParams } from '../schemas/rule_schemas'; +import { ruleStatusSavedObjectsClientFactory } from '../signals/rule_status_saved_objects_client'; + +interface EnableRuleArgs { + rule: SanitizedAlert; + alertsClient: AlertsClient; + savedObjectsClient: SavedObjectsClientContract; +} + +/** + * Enables the rule and updates its status to 'going to run' + * + * @param rule - rule to enable + * @param alertsClient - Alerts client + * @param savedObjectsClient - Saved Objects client + */ +export const enableRule = async ({ rule, alertsClient, savedObjectsClient }: EnableRuleArgs) => { + await alertsClient.enable({ id: rule.id }); + + const ruleStatusClient = ruleStatusSavedObjectsClientFactory(savedObjectsClient); + const ruleCurrentStatus = await ruleStatusClient.find({ + perPage: 1, + sortField: 'statusDate', + sortOrder: 'desc', + search: rule.id, + searchFields: ['alertId'], + }); + + // set current status for this rule to be 'going to run' + if (ruleCurrentStatus && ruleCurrentStatus.saved_objects.length > 0) { + const currentStatusToDisable = ruleCurrentStatus.saved_objects[0]; + await ruleStatusClient.update(currentStatusToDisable.id, { + ...currentStatusToDisable.attributes, + status: 'going to run', + }); + } +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts index 754aaf67c32243..eae5ccd2f6ffde 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts @@ -18,7 +18,7 @@ export const getFilter = (filter: string | null | undefined) => { } }; -export const findRules = async ({ +export const findRules = ({ alertsClient, perPage, page, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts index b9a88bc36a812f..72af7ebc340cd9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts @@ -5,19 +5,19 @@ * 2.0. */ -import { defaults } from 'lodash/fp'; import { validate } from '@kbn/securitysolution-io-ts-utils'; +import { defaults } from 'lodash/fp'; import { PartialAlert } from '../../../../../alerting/server'; import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions'; -import { PatchRulesOptions } from './types'; -import { addTags } from './add_tags'; -import { calculateVersion, calculateName, calculateInterval, removeUndefined } from './utils'; -import { ruleStatusSavedObjectsClientFactory } from '../signals/rule_status_saved_objects_client'; -import { internalRuleUpdate, RuleParams } from '../schemas/rule_schemas'; import { normalizeMachineLearningJobIds, normalizeThresholdObject, } from '../../../../common/detection_engine/utils'; +import { internalRuleUpdate, RuleParams } from '../schemas/rule_schemas'; +import { addTags } from './add_tags'; +import { enableRule } from './enable_rule'; +import { PatchRulesOptions } from './types'; +import { calculateInterval, calculateName, calculateVersion, removeUndefined } from './utils'; class PatchError extends Error { public readonly statusCode: number; @@ -200,25 +200,7 @@ export const patchRules = async ({ if (rule.enabled && enabled === false) { await alertsClient.disable({ id: rule.id }); } else if (!rule.enabled && enabled === true) { - await alertsClient.enable({ id: rule.id }); - - const ruleStatusClient = ruleStatusSavedObjectsClientFactory(savedObjectsClient); - const ruleCurrentStatus = await ruleStatusClient.find({ - perPage: 1, - sortField: 'statusDate', - sortOrder: 'desc', - search: rule.id, - searchFields: ['alertId'], - }); - - // set current status for this rule to be 'going to run' - if (ruleCurrentStatus && ruleCurrentStatus.saved_objects.length > 0) { - const currentStatusToDisable = ruleCurrentStatus.saved_objects[0]; - await ruleStatusClient.update(currentStatusToDisable.id, { - ...currentStatusToDisable.attributes, - status: 'going to run', - }); - } + await enableRule({ rule, alertsClient, savedObjectsClient }); } else { // enabled is null or undefined and we do not touch the rule } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts index 601f3ebaa0f9e6..d029393ce781e4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts @@ -68,6 +68,7 @@ import { MetaOrUndefined, Description, Enabled, + Id, IdOrUndefined, RuleIdOrUndefined, EnabledOrUndefined, @@ -105,6 +106,7 @@ import { Alert, SanitizedAlert } from '../../../../../alerting/common'; import { SIGNALS_ID } from '../../../../common/constants'; import { PartialFilter } from '../types'; import { RuleParams } from '../schemas/rule_schemas'; +import { RuleStatusSavedObjectsClient } from '../signals/rule_status_saved_objects_client'; export type RuleAlertType = Alert; @@ -329,8 +331,10 @@ export interface ReadRuleOptions { export interface DeleteRuleOptions { alertsClient: AlertsClient; - id: IdOrUndefined; - ruleId: RuleIdOrUndefined; + savedObjectsClient: SavedObjectsClientContract; + ruleStatusClient: RuleStatusSavedObjectsClient; + ruleStatuses: SavedObjectsFindResponse; + id: Id; } export interface FindRuleOptions { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts index 38cae8d1cf50fa..0fac804163afab 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts @@ -13,9 +13,9 @@ import { PartialAlert } from '../../../../../alerting/server'; import { readRules } from './read_rules'; import { UpdateRulesOptions } from './types'; import { addTags } from './add_tags'; -import { ruleStatusSavedObjectsClientFactory } from '../signals/rule_status_saved_objects_client'; import { typeSpecificSnakeToCamel } from '../schemas/rule_converters'; import { InternalRuleUpdate, RuleParams } from '../schemas/rule_schemas'; +import { enableRule } from './enable_rule'; export const updateRules = async ({ alertsClient, @@ -88,25 +88,7 @@ export const updateRules = async ({ if (existingRule.enabled && enabled === false) { await alertsClient.disable({ id: existingRule.id }); } else if (!existingRule.enabled && enabled === true) { - await alertsClient.enable({ id: existingRule.id }); - - const ruleStatusClient = ruleStatusSavedObjectsClientFactory(savedObjectsClient); - const ruleCurrentStatus = await ruleStatusClient.find({ - perPage: 1, - sortField: 'statusDate', - sortOrder: 'desc', - search: existingRule.id, - searchFields: ['alertId'], - }); - - // set current status for this rule to be 'going to run' - if (ruleCurrentStatus && ruleCurrentStatus.saved_objects.length > 0) { - const currentStatusToDisable = ruleCurrentStatus.saved_objects[0]; - await ruleStatusClient.update(currentStatusToDisable.id, { - ...currentStatusToDisable.attributes, - status: 'going to run', - }); - } + await enableRule({ rule: existingRule, alertsClient, savedObjectsClient }); } return { ...update, enabled }; }; diff --git a/x-pack/plugins/security_solution/server/routes/index.ts b/x-pack/plugins/security_solution/server/routes/index.ts index 0245d4cb99cc0f..00de66c0dec284 100644 --- a/x-pack/plugins/security_solution/server/routes/index.ts +++ b/x-pack/plugins/security_solution/server/routes/index.ts @@ -31,6 +31,7 @@ import { createRulesBulkRoute } from '../lib/detection_engine/routes/rules/creat import { updateRulesBulkRoute } from '../lib/detection_engine/routes/rules/update_rules_bulk_route'; import { patchRulesBulkRoute } from '../lib/detection_engine/routes/rules/patch_rules_bulk_route'; import { deleteRulesBulkRoute } from '../lib/detection_engine/routes/rules/delete_rules_bulk_route'; +import { performBulkActionRoute } from '../lib/detection_engine/routes/rules/perform_bulk_action_route'; import { importRulesRoute } from '../lib/detection_engine/routes/rules/import_rules_route'; import { exportRulesRoute } from '../lib/detection_engine/routes/rules/export_rules_route'; import { findRulesStatusesRoute } from '../lib/detection_engine/routes/rules/find_rules_status_route'; @@ -81,6 +82,7 @@ export const initRoutes = ( updateRulesBulkRoute(router, ml); patchRulesBulkRoute(router, ml); deleteRulesBulkRoute(router); + performBulkActionRoute(router, ml); createTimelinesRoute(router, config, security); patchTimelinesRoute(router, config, security); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 8b39e99782fe1d..4bc03b4ba6e2aa 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -5243,7 +5243,6 @@ "xpack.apm.agentConfig.chooseService.editButton": "編集", "xpack.apm.agentConfig.chooseService.service.environment.label": "環境", "xpack.apm.agentConfig.chooseService.service.name.label": "サービス名", - "xpack.apm.agentConfig.chooseService.title": "サービスを選択", "xpack.apm.agentConfig.circuitBreakerEnabled.description": "Circuit Breaker を有効にすべきかどうかを指定するブール値。 有効にすると、エージェントは定期的にストレス監視をポーリングして、システム/プロセス/JVMのストレス状態を検出します。監視のいずれかがストレスの兆候を検出した場合、`recording`構成オプションの設定が「false」であるかのようにエージェントは一時停止し、リソース消費を最小限に抑えられます。一時停止した場合、エージェントはストレス状態が緩和されたかどうかを検出するために同じ監視のポーリングを継続します。すべての監視でシステム/プロセス/JVMにストレスがないことが認められると、エージェントは再開して完全に機能します。", "xpack.apm.agentConfig.circuitBreakerEnabled.label": "Cirtcuit Breaker が有効", "xpack.apm.agentConfig.configTable.appliedTooltipMessage": "1 つ以上のエージェントにより適用されました", @@ -5302,8 +5301,6 @@ "xpack.apm.agentConfig.servicePage.service.description": "構成するサービスを選択してください。", "xpack.apm.agentConfig.servicePage.service.fieldLabel": "サービス名", "xpack.apm.agentConfig.servicePage.service.title": "サービス", - "xpack.apm.agentConfig.servicePage.title": "サービスを選択", - "xpack.apm.agentConfig.settings.title": "構成オプション", "xpack.apm.agentConfig.settingsPage.discardChangesButton": "変更を破棄", "xpack.apm.agentConfig.settingsPage.notFound.message": "リクエストされた構成が存在しません", "xpack.apm.agentConfig.settingsPage.notFound.title": "申し訳ございません、エラーが発生しました", @@ -5322,7 +5319,6 @@ "xpack.apm.agentConfig.stressMonitorSystemCpuReliefThreshold.label": "ストレス監視システム CPU 緩和しきい値", "xpack.apm.agentConfig.stressMonitorSystemCpuStressThreshold.description": "システムCPU監視でシステムCPUストレスの検出に使用するしきい値。システムCPUが少なくとも「stress_monitor_cpu_duration_threshold」と同じ長さ以上の期間にわたってこのしきい値を超えると、監視機能はこれをストレス状態と見なします。", "xpack.apm.agentConfig.stressMonitorSystemCpuStressThreshold.label": "ストレス監視システム CPU ストレスしきい値", - "xpack.apm.agentConfig.titleText": "エージェント中央構成", "xpack.apm.agentConfig.transactionIgnoreUrl.description": "特定の URL への要求が命令されないように制限するために使用します。この構成では、無視される URL パスのワイルドカードパターンのカンマ区切りのリストを使用できます。受信 HTTP 要求が検出されると、要求パスが、リストの各要素に対してテストされます。たとえば、このリストに「/home/index」を追加すると、一致して、「http://localhost/home/index」と「http://whatever.com/home/index?value1=123」から命令が削除されます。", "xpack.apm.agentConfig.transactionIgnoreUrl.label": "URL に基づくトランザクションを無視", "xpack.apm.agentConfig.transactionMaxSpans.description": "トランザクションごとに記録される範囲を制限します。", @@ -5388,9 +5384,6 @@ "xpack.apm.apply.label": "適用", "xpack.apm.applyFilter": "{title} フィルターを適用", "xpack.apm.applyOptions": "オプションを適用", - "xpack.apm.breadcrumb.serviceMapTitle": "サービスマップ", - "xpack.apm.breadcrumb.servicesTitle": "サービス", - "xpack.apm.breadcrumb.tracesTitle": "トレース", "xpack.apm.chart.annotation.version": "バージョン", "xpack.apm.chart.cpuSeries.processAverageLabel": "プロセス平均", "xpack.apm.chart.cpuSeries.processMaxLabel": "プロセス最大", @@ -5783,7 +5776,6 @@ "xpack.apm.settings.anomalyDetection.addEnvironments.selectorLabel": "環境", "xpack.apm.settings.anomalyDetection.addEnvironments.selectorPlaceholder": "環境を選択または追加", "xpack.apm.settings.anomalyDetection.addEnvironments.titleText": "環境を選択", - "xpack.apm.settings.anomalyDetection.descriptionText": "機械学習異常検知統合により、レイテンシの異常を特定することで、各構成された環境で、サービスのアプリケーション正常性ステータスインジケーターが有効になります。", "xpack.apm.settings.anomalyDetection.jobList.actionColumnLabel": "アクション", "xpack.apm.settings.anomalyDetection.jobList.addEnvironments": "MLジョブを作成", "xpack.apm.settings.anomalyDetection.jobList.emptyListText": "異常検知ジョブがありません。", @@ -5793,7 +5785,6 @@ "xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText": "異常検知を新しい環境に追加するには、機械学習ジョブを作成します。既存の機械学習ジョブは、{mlJobsLink}で管理できます。", "xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText.mlJobsLinkText": "機械学習", "xpack.apm.settings.anomalyDetection.jobList.mlJobLinkText": "MLでジョブを表示", - "xpack.apm.settings.anomalyDetection.titleText": "異常検知", "xpack.apm.settings.apmIndices.applyButton": "変更を適用", "xpack.apm.settings.apmIndices.applyChanges.failed.text": "インデックスの適用時に何か問題が発生しました。エラー:{errorMessage}", "xpack.apm.settings.apmIndices.applyChanges.failed.title": "インデックスが適用できませんでした。", @@ -5811,8 +5802,6 @@ "xpack.apm.settings.apmIndices.title": "インデックス", "xpack.apm.settings.apmIndices.transactionIndicesLabel": "トランザクションインデックス", "xpack.apm.settings.customizeApp": "アプリをカスタマイズ", - "xpack.apm.settings.customizeApp.description": "次の設定でAPMアプリ経験を拡張します。", - "xpack.apm.settings.customizeApp.title": "アプリをカスタマイズ", "xpack.apm.settings.customizeUI.customLink": "カスタムリンク", "xpack.apm.settings.customizeUI.customLink.create.failed": "リンクを保存できませんでした!", "xpack.apm.settings.customizeUI.customLink.create.failed.message": "リンクを保存するときに問題が発生しました。エラー:「{errorMessage}」", @@ -5861,7 +5850,6 @@ "xpack.apm.settings.customizeUI.customLink.table.noResultFound": "\"{value}\"に対する結果が見つかりませんでした。", "xpack.apm.settings.customizeUI.customLink.table.url": "URL", "xpack.apm.settings.indices": "インデックス", - "xpack.apm.settings.pageTitle": "設定", "xpack.apm.settingsLinkLabel": "設定", "xpack.apm.setupInstructionsButtonLabel": "セットアップの手順", "xpack.apm.significanTerms.license.text": "相関関係APIを使用するには、Elastic Platinumライセンスのサブスクリプションが必要です。", @@ -20099,7 +20087,6 @@ "xpack.securitySolution.detectionEngine.rules.allRules.tabs.monitoring": "ルール監視", "xpack.securitySolution.detectionEngine.rules.allRules.tabs.rules": "ルール", "xpack.securitySolution.detectionEngine.rules.backOptionsHeader": "検出に戻る", - "xpack.securitySolution.detectionEngine.rules.components.genericDownloader.exportFailureTitle": "データをエクスポートできませんでした…", "xpack.securitySolution.detectionEngine.rules.components.ruleActionsOverflow.allActionsTitle": "すべてのアクション", "xpack.securitySolution.detectionEngine.rules.continueButtonTitle": "続行", "xpack.securitySolution.detectionEngine.rules.create.successfullyCreatedRuleTitle": "{ruleName}が作成されました", @@ -21390,7 +21377,6 @@ "xpack.securitySolution.trustedapps.list.actions.delete": "削除", "xpack.securitySolution.trustedapps.list.actions.delete.description": "このエントリを削除", "xpack.securitySolution.trustedapps.list.addButton": "信頼できるアプリケーションを追加", - "xpack.securitySolution.trustedapps.list.backButton": "戻る", "xpack.securitySolution.trustedapps.list.columns.actions": "アクション", "xpack.securitySolution.trustedapps.list.pageTitle": "信頼できるアプリケーション", "xpack.securitySolution.trustedapps.listEmptyState.message": "現在、エンドポイントには信頼できるアプリケーションがありません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index a5edefdf9f9bf6..46bdb83c42528b 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -5272,7 +5272,6 @@ "xpack.apm.agentConfig.chooseService.editButton": "编辑", "xpack.apm.agentConfig.chooseService.service.environment.label": "环境", "xpack.apm.agentConfig.chooseService.service.name.label": "服务名称", - "xpack.apm.agentConfig.chooseService.title": "选择服务", "xpack.apm.agentConfig.circuitBreakerEnabled.description": "指定是否应启用断路器的布尔值。 启用时,代理定期轮询压力监测以检测系统/进程/JVM 压力状态。如果任意监测检测到压力迹象,代理将会暂停,就如 `recording` 配置选项已设置为 `false` 一样,从而使资源消耗降低至最小程度。暂停时,代理继续轮询相同的监测,以便检测压力状态是否已缓解。如果所有监测认为系统/进程/JVM 不再承受压力时,代理将完全恢复正常运行。", "xpack.apm.agentConfig.circuitBreakerEnabled.label": "断路器已启用", "xpack.apm.agentConfig.configTable.appliedTooltipMessage": "已至少由一个代理应用", @@ -5331,8 +5330,6 @@ "xpack.apm.agentConfig.servicePage.service.description": "选择要配置的服务。", "xpack.apm.agentConfig.servicePage.service.fieldLabel": "服务名称", "xpack.apm.agentConfig.servicePage.service.title": "服务", - "xpack.apm.agentConfig.servicePage.title": "选择服务", - "xpack.apm.agentConfig.settings.title": "配置选项", "xpack.apm.agentConfig.settingsPage.discardChangesButton": "放弃更改", "xpack.apm.agentConfig.settingsPage.notFound.message": "请求的配置不存在", "xpack.apm.agentConfig.settingsPage.notFound.title": "抱歉,有错误", @@ -5351,7 +5348,6 @@ "xpack.apm.agentConfig.stressMonitorSystemCpuReliefThreshold.label": "压力监测系统 cpu 缓解阈值", "xpack.apm.agentConfig.stressMonitorSystemCpuStressThreshold.description": "系统 CPU 监测用于检测系统 CPU 压力的阈值。如果系统 CPU 超过此阈值的持续时间至少有 `stress_monitor_cpu_duration_threshold`,监测会将其视为压力状态。", "xpack.apm.agentConfig.stressMonitorSystemCpuStressThreshold.label": "压力监测系统 cpu 压力阈值", - "xpack.apm.agentConfig.titleText": "代理中央配置", "xpack.apm.agentConfig.transactionIgnoreUrl.description": "用于限制对某些 URL 的请求不被检测。此配置接受应忽略的 URL 路径的通配符模式逗号分隔列表。当监测到传入 HTTP 请求时,会根据此列表中的每个元素测试其请求路径。例如,将 `/home/index` 添加到此列表中后,该元素将匹配并删除 `http://localhost/home/index` 和 `http://whatever.com/home/index?value1=123` 的检测", "xpack.apm.agentConfig.transactionIgnoreUrl.label": "基于 URL 忽略事务", "xpack.apm.agentConfig.transactionMaxSpans.description": "限制每个事务记录的跨度数量。", @@ -5417,9 +5413,6 @@ "xpack.apm.apply.label": "应用", "xpack.apm.applyFilter": "应用 {title} 筛选", "xpack.apm.applyOptions": "应用选项", - "xpack.apm.breadcrumb.serviceMapTitle": "服务地图", - "xpack.apm.breadcrumb.servicesTitle": "服务", - "xpack.apm.breadcrumb.tracesTitle": "追溯", "xpack.apm.chart.annotation.version": "版本", "xpack.apm.chart.cpuSeries.processAverageLabel": "进程平均值", "xpack.apm.chart.cpuSeries.processMaxLabel": "进程最大值", @@ -5817,7 +5810,6 @@ "xpack.apm.settings.anomalyDetection.addEnvironments.selectorLabel": "环境", "xpack.apm.settings.anomalyDetection.addEnvironments.selectorPlaceholder": "选择或添加环境", "xpack.apm.settings.anomalyDetection.addEnvironments.titleText": "选择环境", - "xpack.apm.settings.anomalyDetection.descriptionText": "Machine Learning 异常检测集成通过识别延迟异常来为每个已配置环境中的服务启用应用程序运行状态指标。", "xpack.apm.settings.anomalyDetection.jobList.actionColumnLabel": "操作", "xpack.apm.settings.anomalyDetection.jobList.addEnvironments": "创建 ML 作业", "xpack.apm.settings.anomalyDetection.jobList.emptyListText": "无异常检测作业。", @@ -5827,7 +5819,6 @@ "xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText": "要将异常检测添加到新环境,请创建 Machine Learning 作业。现有 Machine Learning 作业可在 {mlJobsLink} 中进行管理。", "xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText.mlJobsLinkText": "Machine Learning", "xpack.apm.settings.anomalyDetection.jobList.mlJobLinkText": "在 ML 中查看作业", - "xpack.apm.settings.anomalyDetection.titleText": "异常检测", "xpack.apm.settings.apmIndices.applyButton": "应用更改", "xpack.apm.settings.apmIndices.applyChanges.failed.text": "应用索引时出现问题。错误:{errorMessage}", "xpack.apm.settings.apmIndices.applyChanges.failed.title": "无法应用索引。", @@ -5845,8 +5836,6 @@ "xpack.apm.settings.apmIndices.title": "索引", "xpack.apm.settings.apmIndices.transactionIndicesLabel": "事务索引", "xpack.apm.settings.customizeApp": "定制应用", - "xpack.apm.settings.customizeApp.description": "使用以下设置扩展 APM 应用体验。", - "xpack.apm.settings.customizeApp.title": "定制应用", "xpack.apm.settings.customizeUI.customLink": "定制链接", "xpack.apm.settings.customizeUI.customLink.create.failed": "链接无法保存!", "xpack.apm.settings.customizeUI.customLink.create.failed.message": "保存链接时出现了问题。错误:“{errorMessage}”", @@ -5895,7 +5884,6 @@ "xpack.apm.settings.customizeUI.customLink.table.noResultFound": "没有“{value}”的结果。", "xpack.apm.settings.customizeUI.customLink.table.url": "URL", "xpack.apm.settings.indices": "索引", - "xpack.apm.settings.pageTitle": "设置", "xpack.apm.settingsLinkLabel": "设置", "xpack.apm.setupInstructionsButtonLabel": "设置说明", "xpack.apm.significanTerms.license.text": "要使用相关性 API,必须订阅 Elastic 白金级许可证。", @@ -20384,13 +20372,11 @@ "xpack.securitySolution.detectionEngine.rules.allRules.showingExceptionLists": "正在显示 {totalLists} 个{totalLists, plural, other {列表}}", "xpack.securitySolution.detectionEngine.rules.allRules.showingRulesTitle": "正在显示 {totalRules} 个{totalRules, plural, other {规则}}", "xpack.securitySolution.detectionEngine.rules.allRules.successfullyDuplicatedRulesTitle": "已成功复制 {totalRules, plural, other {{totalRules} 个规则}}", - "xpack.securitySolution.detectionEngine.rules.allRules.successfullyExportedRulesTitle": "已成功导出{totalRules, plural, =0 {所有规则} other { {totalRules} 个规则}}", "xpack.securitySolution.detectionEngine.rules.allRules.tableTitle": "所有规则", "xpack.securitySolution.detectionEngine.rules.allRules.tabs.exceptions": "例外列表", "xpack.securitySolution.detectionEngine.rules.allRules.tabs.monitoring": "规则监测", "xpack.securitySolution.detectionEngine.rules.allRules.tabs.rules": "规则", "xpack.securitySolution.detectionEngine.rules.backOptionsHeader": "返回到检测", - "xpack.securitySolution.detectionEngine.rules.components.genericDownloader.exportFailureTitle": "无法导出数据……", "xpack.securitySolution.detectionEngine.rules.components.ruleActionsOverflow.allActionsTitle": "所有操作", "xpack.securitySolution.detectionEngine.rules.continueButtonTitle": "继续", "xpack.securitySolution.detectionEngine.rules.create.successfullyCreatedRuleTitle": "{ruleName} 已创建", @@ -21726,7 +21712,6 @@ "xpack.securitySolution.trustedapps.list.actions.delete": "移除", "xpack.securitySolution.trustedapps.list.actions.delete.description": "移除此条目", "xpack.securitySolution.trustedapps.list.addButton": "添加受信任的应用程序", - "xpack.securitySolution.trustedapps.list.backButton": "返回", "xpack.securitySolution.trustedapps.list.columns.actions": "操作", "xpack.securitySolution.trustedapps.list.pageTitle": "受信任的应用程序", "xpack.securitySolution.trustedapps.list.totalCount": "{totalItemCount, plural, other {# 个受信任的应用程序}}", diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts index fd3675a2e47e62..3c5e04ee1f64ea 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts @@ -35,6 +35,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./update_rules')); loadTestFile(require.resolve('./update_rules_bulk')); loadTestFile(require.resolve('./patch_rules_bulk')); + loadTestFile(require.resolve('./perform_bulk_action')); loadTestFile(require.resolve('./patch_rules')); loadTestFile(require.resolve('./read_privileges')); loadTestFile(require.resolve('./query_signals')); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/perform_bulk_action.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/perform_bulk_action.ts new file mode 100644 index 00000000000000..53613624067e16 --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/perform_bulk_action.ts @@ -0,0 +1,152 @@ +/* + * 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 expect from '@kbn/expect'; + +import { + DETECTION_ENGINE_RULES_BULK_ACTION, + DETECTION_ENGINE_RULES_URL, +} from '../../../../plugins/security_solution/common/constants'; +import { BulkAction } from '../../../../plugins/security_solution/common/detection_engine/schemas/common/schemas'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { + binaryToString, + createRule, + createSignalsIndex, + deleteAllAlerts, + deleteSignalsIndex, + getSimpleRule, + getSimpleRuleOutput, + removeServerGeneratedProperties, +} from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + + describe('perform_bulk_action', () => { + beforeEach(async () => { + await createSignalsIndex(supertest); + }); + + afterEach(async () => { + await deleteSignalsIndex(supertest); + await deleteAllAlerts(supertest); + }); + + it('should export rules', async () => { + await createRule(supertest, getSimpleRule()); + + const { body } = await supertest + .post(DETECTION_ENGINE_RULES_BULK_ACTION) + .set('kbn-xsrf', 'true') + .send({ query: '', action: BulkAction.export }) + .expect(200) + .expect('Content-Type', 'application/ndjson') + .expect('Content-Disposition', 'attachment; filename="rules_export.ndjson"') + .parse(binaryToString); + + const [ruleJson, exportDetailsJson] = body.toString().split(/\n/); + + const rule = removeServerGeneratedProperties(JSON.parse(ruleJson)); + expect(rule).to.eql(getSimpleRuleOutput()); + + const exportDetails = JSON.parse(exportDetailsJson); + expect(exportDetails).to.eql({ + exported_count: 1, + missing_rules: [], + missing_rules_count: 0, + }); + }); + + it('should delete rules', async () => { + const ruleId = 'ruleId'; + await createRule(supertest, getSimpleRule(ruleId)); + + const { body } = await supertest + .post(DETECTION_ENGINE_RULES_BULK_ACTION) + .set('kbn-xsrf', 'true') + .send({ query: '', action: BulkAction.delete }) + .expect(200); + + expect(body).to.eql({ success: true, rules_count: 1 }); + + await supertest + .get(`${DETECTION_ENGINE_RULES_URL}?rule_id=${ruleId}`) + .set('kbn-xsrf', 'true') + .expect(404); + }); + + it('should enable rules', async () => { + const ruleId = 'ruleId'; + await createRule(supertest, getSimpleRule(ruleId)); + + const { body } = await supertest + .post(DETECTION_ENGINE_RULES_BULK_ACTION) + .set('kbn-xsrf', 'true') + .send({ query: '', action: BulkAction.enable }) + .expect(200); + + expect(body).to.eql({ success: true, rules_count: 1 }); + + const { body: ruleBody } = await supertest + .get(`${DETECTION_ENGINE_RULES_URL}?rule_id=${ruleId}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const referenceRule = getSimpleRuleOutput(ruleId); + referenceRule.enabled = true; + + const storedRule = removeServerGeneratedProperties(ruleBody); + + expect(storedRule).to.eql(referenceRule); + }); + + it('should disable rules', async () => { + const ruleId = 'ruleId'; + await createRule(supertest, getSimpleRule(ruleId, true)); + + const { body } = await supertest + .post(DETECTION_ENGINE_RULES_BULK_ACTION) + .set('kbn-xsrf', 'true') + .send({ query: '', action: BulkAction.disable }) + .expect(200); + + expect(body).to.eql({ success: true, rules_count: 1 }); + + const { body: ruleBody } = await supertest + .get(`${DETECTION_ENGINE_RULES_URL}?rule_id=${ruleId}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const referenceRule = getSimpleRuleOutput(ruleId); + const storedRule = removeServerGeneratedProperties(ruleBody); + + expect(storedRule).to.eql(referenceRule); + }); + + it('should duplicate rules', async () => { + const ruleId = 'ruleId'; + await createRule(supertest, getSimpleRule(ruleId)); + + const { body } = await supertest + .post(DETECTION_ENGINE_RULES_BULK_ACTION) + .set('kbn-xsrf', 'true') + .send({ query: '', action: BulkAction.duplicate }) + .expect(200); + + expect(body).to.eql({ success: true, rules_count: 1 }); + + const { body: rulesResponse } = await supertest + .get(`${DETECTION_ENGINE_RULES_URL}/_find`) + .set('kbn-xsrf', 'true') + .expect(200); + + expect(rulesResponse.total).to.eql(2); + }); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/runtime.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/runtime.ts index 4132b63415fccd..94cc390e0e6ef6 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/runtime.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/runtime.ts @@ -32,13 +32,13 @@ export default ({ getService }: FtrProviderContext) => { describe('Regular runtime field mappings', () => { beforeEach(async () => { await createSignalsIndex(supertest); - await esArchiver.load('security_solution/runtime'); + await esArchiver.load('x-pack/test/functional/es_archives/security_solution/runtime'); }); afterEach(async () => { await deleteSignalsIndex(supertest); await deleteAllAlerts(supertest); - await esArchiver.unload('security_solution/runtime'); + await esArchiver.unload('x-pack/test/functional/es_archives/security_solution/runtime'); }); it('should copy normal non-runtime data set from the source index into the signals index in the same position when the target is ECS compatible', async () => { @@ -68,13 +68,17 @@ export default ({ getService }: FtrProviderContext) => { describe('Runtime field mappings that have conflicts within them', () => { beforeEach(async () => { await createSignalsIndex(supertest); - await esArchiver.load('security_solution/runtime_conflicting_fields'); + await esArchiver.load( + 'x-pack/test/functional/es_archives/security_solution/runtime_conflicting_fields' + ); }); afterEach(async () => { await deleteSignalsIndex(supertest); await deleteAllAlerts(supertest); - await esArchiver.unload('security_solution/runtime_conflicting_fields'); + await esArchiver.unload( + 'x-pack/test/functional/es_archives/security_solution/runtime_conflicting_fields' + ); }); // TODO: Make the overrides of runtime fields override the host.name in this use case. diff --git a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts index 5cf0db2a6d9171..5e4a580473dd1a 100644 --- a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts +++ b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts @@ -48,15 +48,15 @@ export default function (providerContext: FtrProviderContext) { describe('fleet_telemetry', () => { skipIfNoDockerRegistry(providerContext); before(async () => { - await esArchiver.load('empty_kibana'); - await esArchiver.load('fleet/empty_fleet_server'); + await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'); + await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server'); }); setupFleetAndAgents(providerContext); after(async () => { - await esArchiver.unload('empty_kibana'); - await esArchiver.unload('fleet/empty_fleet_server'); + await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana'); + await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server'); }); before(async () => {