From 6fb2b4ad833589604ca926282195f2ae99489fd6 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 4 May 2021 12:02:17 +0200 Subject: [PATCH] [Search Sessions] Fix display of expired session state in management (#98915) --- .../components/table/table.test.tsx | 6 +-- .../search/sessions_mgmt/lib/api.test.ts | 29 +++++++++++++ .../public/search/sessions_mgmt/lib/api.ts | 34 +++++++++++++-- .../public/search/sessions_mgmt/types.ts | 4 +- .../data/search_sessions/data.json.gz | Bin 2650 -> 2680 bytes .../search_sessions_management_page.ts | 2 +- .../search_sessions/sessions_management.ts | 41 +++++++++++------- 7 files changed, 93 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/table.test.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/table.test.tsx index 123cc3dcb97c..4d97092209c6 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/table.test.tsx +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/table.test.tsx @@ -129,10 +129,10 @@ describe('Background Search Session Management Table', () => { expect(table.find('tbody td').map((node) => node.text())).toMatchInlineSnapshot(` Array [ "App", - "Namevery background search", - "StatusIn progress", + "Namevery background search ", + "StatusExpired", "Created2 Dec, 2020, 00:19:32", - "Expiration7 Dec, 2020, 00:19:32", + "Expiration--", "", "", ] diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts index f1f38fecfe01..3857b08ad0a3 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts @@ -87,6 +87,35 @@ describe('Search Sessions Management API', () => { `); }); + test('completed session with expired time is showed as expired', async () => { + sessionsClient.find = jest.fn().mockImplementation(async () => { + return { + saved_objects: [ + { + id: 'hello-pizza-123', + attributes: { + name: 'Veggie', + appId: 'pizza', + status: 'complete', + expires: moment().subtract(3, 'days'), + initialState: {}, + restoreState: {}, + }, + }, + ], + } as SavedObjectsFindResponse; + }); + + const api = new SearchSessionsMgmtAPI(sessionsClient, mockConfig, { + urls: mockUrls, + notifications: mockCoreStart.notifications, + application: mockCoreStart.application, + }); + + const res = await api.fetchTableData(); + expect(res[0].status).toBe(SearchSessionStatus.EXPIRED); + }); + test('handle error from sessionsClient response', async () => { sessionsClient.find = jest.fn().mockRejectedValue(new Error('implementation is so bad')); diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts index 943fc7d26d36..3710dfa16e76 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts @@ -17,12 +17,16 @@ import { } from '../../../../../../../src/plugins/data/public'; import { SearchSessionStatus } from '../../../../../../../src/plugins/data/common'; import { ACTION } from '../components/actions'; -import { PersistedSearchSessionSavedObjectAttributes, UISession } from '../types'; +import { + PersistedSearchSessionSavedObjectAttributes, + UISearchSessionState, + UISession, +} from '../types'; import { SessionsConfigSchema } from '..'; type UrlGeneratorsStart = SharePluginStart['urlGenerators']; -function getActions(status: SearchSessionStatus) { +function getActions(status: UISearchSessionState) { const actions: ACTION[] = []; actions.push(ACTION.INSPECT); actions.push(ACTION.RENAME); @@ -30,9 +34,33 @@ function getActions(status: SearchSessionStatus) { actions.push(ACTION.EXTEND); actions.push(ACTION.DELETE); } + + if (status === SearchSessionStatus.EXPIRED) { + actions.push(ACTION.DELETE); + } + return actions; } +/** + * Status we display on mgtm UI might be different from the one inside the saved object + * @param status + */ +function getUIStatus(session: PersistedSearchSessionSavedObjectAttributes): UISearchSessionState { + const isSessionExpired = () => { + const curTime = moment(); + return curTime.diff(moment(session.expires), 'ms') > 0; + }; + + switch (session.status) { + case SearchSessionStatus.COMPLETE: + case SearchSessionStatus.IN_PROGRESS: + return isSessionExpired() ? SearchSessionStatus.EXPIRED : session.status; + } + + return session.status; +} + async function getUrlFromState( urls: UrlGeneratorsStart, urlGeneratorId: string, @@ -59,12 +87,12 @@ const mapToUISession = (urls: UrlGeneratorsStart, config: SessionsConfigSchema) appId, created, expires, - status, urlGeneratorId, initialState, restoreState, } = savedObject.attributes; + const status = getUIStatus(savedObject.attributes); const actions = getActions(status); // TODO: initialState should be saved without the searchSessionID diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts index 369eac450e07..d0d5ee9fb17d 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts @@ -25,13 +25,15 @@ export type PersistedSearchSessionSavedObjectAttributes = SearchSessionSavedObje > >; +export type UISearchSessionState = SearchSessionStatus; + export interface UISession { id: string; name: string; appId: string; created: string; expires: string | null; - status: SearchSessionStatus; + status: UISearchSessionState; actions?: ACTION[]; reloadUrl: string; restoreUrl: string; diff --git a/x-pack/test/functional/es_archives/data/search_sessions/data.json.gz b/x-pack/test/functional/es_archives/data/search_sessions/data.json.gz index fff020036a8e3de67513dbdb85f1bf96c850605d..9528149d3c0f91f0881f6763a5a97d0e7c61ca74 100644 GIT binary patch delta 2676 zcmV-)3XApH6!;W>ABzYGi3f~e00U%UbYU)Pb8l_{?VRmX+SnJz-|t`H_3`uA%9;NuRij_?pgCwgVs9{N^We;-JRC=ap!Qqc}AUW&<5(B9Yx2T zUS!`QVuyUtp-tL6Jo@18#<+3SAhXI9rkKtWapTb>2}PKXW>AL9+j2bQVSDRu7$lS! zqRYTyreY$Ef-rH=6l;wbr-51%V~`(rpckLtEc}8;yGX<}J?5X@As0$z9`JmFh>IRt;Y`X_0bXXzv&j z23aY%MAjNZp&z7O34(a z!UtyIwnGvzLd-F4W8^&dbWsDnlXkMd-+ag0-TFzz@K@{O3x0+IOJIHG18b|K_N|$M}JJc#ncKA&NmVsg2~tLZ^tz~icoZW z`mP@Nq<-D*?$K_oN~s~Z)xuY?Q%J{(Tcj!Cu5^r8VlSoCNKp?r1VN=u5Gq*fC6?L< zgHd44sKDK#Qo2{&s2Mxbe;;)kw{3D{qMB|vbaHcYR>eSS%fg?VV(!oNXH za@Ohe>Xs%V!o3gYqnoT-Z_)EnuXkE0{C~Z>6~ni}2_q2fOky0kwV)Q`G{6E}&XW*? zo1tHTU?{SR#saozgiDNJ5d3-(HT82}yS(X*JdRFVXWi7FbbFSapxbVzb$`}9 zY~GyE{ofj=m!C}1pO|hH`*y2tvx0*~NCm+e~#gLF^~OwxuE?t6tVoBw$)APIrpcZ_x*4YGrAP&-CI zM-n)AQ6R9@;KwAmd>%ULo zGSJG--#9T))_?N<+~T6yJLYX?d){@wni!W4X)mE~am! zQnTo%S@JHV0qk&`&8I!sYai|(@3jst_C9>Lh+4m2ysI^9t-a21Ykzy5O7>Z*1qkS( z9JpUV_X_)_?JwUn@nv^^VTyl^r?iW$zkm7Vua%!+u(E4l$m~FyhIbfP;*J4#-a#V9 zMk;Kn!~exIj6v?k*O32`Cm71<3|9r*@;#{>k=GxNDAAb**vP|mH{zs#MFvtm{Y zsKz++A-gD-OnJnI+(DwVRG-J6mh$Mh3@qR3z`EZe|1pa;`dHM*_fV^9dTS@G{83p{ z#+;a81wz4Z6eY_r_rCr1xLa%e_mo=*hyOp6`}mPk`tc)vX39B}UYn&)>E-KS+#m&$ z8DBzL`37^Z2!C^QgSi*RTvgXwJ89*Q%3_)0JVZLVUZj&xO*-<-q`MyEQ)_lxrw!#^6Xp1Za_d34A9~)}N$VlX{Wyz<+<)dF#_9E9oPI*av9eO^nHhJP znMr>M;P5N?WG-acINRXu72!>6@b=<(t7dm=C$0QZS$yv`55Ntt*JpD0DL<3rWu5pl z!z~HvvQOmjlYMVyz1g<;t&>-XH@U&vi{q`D;jNvt@<(M+^|wwiUoXP(CnTIGOC_F} zaAq=E27kB*$h867#=w3Gz^M)3UL0`M{BG@}l|L$r%7A0*1vvJEfRkmZ*8LCu!xnj@TmS%vV`Sd| delta 2646 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 diff --git a/x-pack/test/functional/page_objects/search_sessions_management_page.ts b/x-pack/test/functional/page_objects/search_sessions_management_page.ts index 3f0e6b80b483..86391b568fdf 100644 --- a/x-pack/test/functional/page_objects/search_sessions_management_page.ts +++ b/x-pack/test/functional/page_objects/search_sessions_management_page.ts @@ -33,7 +33,7 @@ export function SearchSessionsPageProvider({ getService, getPageObjects }: FtrPr const viewCell = await row.findByTestSubject('sessionManagementNameCol'); const actionsCell = await row.findByTestSubject('sessionManagementActionsCol'); return { - name: $.findTestSubject('sessionManagementNameCol').text(), + name: $.findTestSubject('sessionManagementNameCol').text().trim(), status: $.findTestSubject('sessionManagementStatusLabel').attr('data-test-status'), mainUrl: $.findTestSubject('sessionManagementNameCol').text(), created: $.findTestSubject('sessionManagementCreatedCol').text(), diff --git a/x-pack/test/search_sessions_integration/tests/apps/management/search_sessions/sessions_management.ts b/x-pack/test/search_sessions_integration/tests/apps/management/search_sessions/sessions_management.ts index bb39c771f0aa..27b4a887075f 100644 --- a/x-pack/test/search_sessions_integration/tests/apps/management/search_sessions/sessions_management.ts +++ b/x-pack/test/search_sessions_integration/tests/apps/management/search_sessions/sessions_management.ts @@ -113,68 +113,79 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const searchSessionList = await PageObjects.searchSessionsManagement.getList(); expect(searchSessionList.length).to.be(10); - expectSnapshot(searchSessionList.map((ss) => [ss.app, ss.name, ss.created, ss.expires])) - .toMatchInline(` + expectSnapshot( + searchSessionList.map((ss) => [ss.app, ss.name, ss.created, ss.expires, ss.status]) + ).toMatchInline(` Array [ Array [ "graph", - "[eCommerce] Orders Test 6 ", + "[eCommerce] Orders Test 6", "16 Feb, 2021, 00:00:00", "--", + "error", ], Array [ "lens", "[eCommerce] Orders Test 7", "15 Feb, 2021, 00:00:00", - "24 Feb, 2021, 00:00:00", + "--", + "expired", ], Array [ "apm", "[eCommerce] Orders Test 8", "14 Feb, 2021, 00:00:00", - "24 Feb, 2021, 00:00:00", + "--", + "expired", ], Array [ "appSearch", "[eCommerce] Orders Test 9", "13 Feb, 2021, 00:00:00", - "24 Feb, 2021, 00:00:00", + "--", + "expired", ], Array [ "auditbeat", "[eCommerce] Orders Test 10", "12 Feb, 2021, 00:00:00", - "24 Feb, 2021, 00:00:00", + "--", + "expired", ], Array [ "code", "[eCommerce] Orders Test 11", "11 Feb, 2021, 00:00:00", - "24 Feb, 2021, 00:00:00", + "--", + "expired", ], Array [ "console", "[eCommerce] Orders Test 12", "10 Feb, 2021, 00:00:00", - "24 Feb, 2021, 00:00:00", + "--", + "expired", ], Array [ "security", - "[eCommerce] Orders Test 5 ", + "[eCommerce] Orders Test 5", "9 Feb, 2021, 00:00:00", - "24 Feb, 2021, 00:00:00", + "--", + "expired", ], Array [ "visualize", - "[eCommerce] Orders Test 4 ", + "[eCommerce] Orders Test 4", "8 Feb, 2021, 00:00:00", "--", + "cancelled", ], Array [ "canvas", "[eCommerce] Orders Test 3", "7 Feb, 2021, 00:00:00", - "24 Feb, 2021, 00:00:00", + "--", + "expired", ], ] `); @@ -201,13 +212,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { "discover", "[eCommerce] Orders Test 2", "6 Feb, 2021, 00:00:00", - "24 Feb, 2021, 00:00:00", + "--", ], Array [ "dashboard", "[eCommerce] Revenue Dashboard", "5 Feb, 2021, 00:00:00", - "24 Feb, 2021, 00:00:00", + "--", ], ] `);