From 03591ca40a2f38222ca6a26f65ca0185703ac444 Mon Sep 17 00:00:00 2001 From: muppi1993 Date: Fri, 18 Nov 2022 20:47:00 +0000 Subject: [PATCH 1/4] added lineage results processing and displaying in table --- app/client/src/components/ResultsTable.vue | 35 ++++++++++++++++++++-- app/client/src/scss/myStyles.scss | 14 +++++++++ app/client/src/store/actions.ts | 31 ++++++++++++++----- app/client/src/store/index.ts | 3 +- app/client/src/store/mutations.ts | 18 ++++++++--- app/client/src/types.ts | 6 ++-- 6 files changed, 91 insertions(+), 16 deletions(-) diff --git a/app/client/src/components/ResultsTable.vue b/app/client/src/components/ResultsTable.vue index 8a08ae7a2..6289af1a4 100644 --- a/app/client/src/components/ResultsTable.vue +++ b/app/client/src/components/ResultsTable.vue @@ -6,6 +6,19 @@ Sketch AMR Cluster + + + + Microreact Network @@ -29,6 +42,9 @@ {{sample.Cluster}} + + {{sample.Lineage}} + Number(a.Cluster) - Number(b.Cluster)); - if (this.analysisStatus.assign === 'finished') { + if (this.analysisStatus.assignClusters === 'finished') { // adding a rowspan property to merge microreact/ network cells from same cluster const tableRowspan = addRowspan(tableSorted); return tableRowspan; diff --git a/app/client/src/scss/myStyles.scss b/app/client/src/scss/myStyles.scss index f8788e656..5caf9f069 100644 --- a/app/client/src/scss/myStyles.scss +++ b/app/client/src/scss/myStyles.scss @@ -176,4 +176,18 @@ small { border-left: 0; border-top: 0; border-bottom: 0; +} + +.dropdown { + position: relative; + display: flex; +} + +.dropdown-toggle { + flex-grow: 1; + padding: 0 !important; +} + +.dropdown-menu { + background-color: white !important; } \ No newline at end of file diff --git a/app/client/src/store/actions.ts b/app/client/src/store/actions.ts index 66055669e..29321e13f 100644 --- a/app/client/src/store/actions.ts +++ b/app/client/src/store/actions.ts @@ -77,21 +77,31 @@ export default { names: filenameMapping, }); if (response) { - commit('setAnalysisStatus', { assign: 'submitted', microreact: 'submitted', network: 'submitted' }); + commit('setAnalysisStatus', { + assignClusters: 'submitted', + assignLineages: 'submitted', + microreact: 'submitted', + network: 'submitted', + }); } }, async getStatus(context: ActionContext) { const { state, dispatch } = context; - const prevAssign = state.analysisStatus.assign; + const prevAssignClusters = state.analysisStatus.assignClusters; + const prevAssignLineages = state.analysisStatus.assignLineages; const response = await api(context) .withSuccess('setAnalysisStatus') .withError('addError') .post(`${serverUrl}/status`, { hash: state.projectHash }); if (response) { - if (response.data.assign === 'finished' && prevAssign !== 'finished') { - dispatch('getAssignResult'); + if (response.data.assignClusters === 'finished' && prevAssignClusters !== 'finished') { + dispatch('getAssignClustersResult'); + } + if (response.data.assignLineages === 'finished' && prevAssignLineages !== 'finished') { + dispatch('getAssignLineagesResult'); } - if ((response.data.network === 'finished' || response.data.network === 'failed') + if ((response.data.assignLineages === 'finished' || response.data.assignLineages === 'failed') + && (response.data.network === 'finished' || response.data.network === 'failed') && (response.data.microreact === 'finished' || response.data.microreact === 'failed')) { clearInterval(state.statusInterval); } @@ -100,12 +110,19 @@ export default { clearInterval(state.statusInterval); } }, - async getAssignResult(context: ActionContext) { + async getAssignClustersResult(context: ActionContext) { const { state } = context; await api(context) .withSuccess('setClusters') .withError('addError') - .post(`${serverUrl}/assignResult`, { projectHash: state.projectHash }); + .post(`${serverUrl}/assignClustersResult`, { projectHash: state.projectHash }); + }, + async getAssignLineagesResult(context: ActionContext) { + const { state } = context; + await api(context) + .withSuccess('setLineages') + .withError('addError') + .post(`${serverUrl}/assignLineagesResult`, { projectHash: state.projectHash }); }, async startStatusPolling(context: ActionContext) { const { dispatch, commit } = context; diff --git a/app/client/src/store/index.ts b/app/client/src/store/index.ts index 4e6f6f4e0..3fa23ede2 100644 --- a/app/client/src/store/index.ts +++ b/app/client/src/store/index.ts @@ -17,7 +17,8 @@ export default new Vuex.Store({ projectHash: null, submitStatus: null, analysisStatus: { - assign: null, + assignClusters: null, + assignLineages: null, microreact: null, network: null, }, diff --git a/app/client/src/store/mutations.ts b/app/client/src/store/mutations.ts index b88488fdd..40d660473 100644 --- a/app/client/src/store/mutations.ts +++ b/app/client/src/store/mutations.ts @@ -1,6 +1,6 @@ import { RootState } from '@/store/state'; import { - Versions, User, IsolateValue, AnalysisStatus, ClusterInfo, BeebopError, + Versions, User, IsolateValue, AnalysisStatus, ClusterInfo, BeebopError, Dict, } from '@/types'; export default { @@ -43,9 +43,19 @@ export default { state.statusInterval = interval; }, setClusters(state: RootState, clusterInfo: ClusterInfo) { - Object.keys(clusterInfo).forEach((element) => { - state.results.perIsolate[clusterInfo[element].hash] - .cluster = clusterInfo[element].cluster; + Object.keys(clusterInfo).forEach((cluster) => { + clusterInfo[cluster].forEach((hash) => { + state.results.perIsolate[hash].cluster = cluster; + }); + }); + }, + setLineages(state: RootState, lineageInfo: Dict>) { + Object.keys(lineageInfo).forEach((hash) => { + state.results.perIsolate[hash].lineage = { + rank1: lineageInfo[hash].rank1, + rank2: lineageInfo[hash].rank2, + rank3: lineageInfo[hash].rank3, + }; }); }, addMicroreactURL(state: RootState, URLinfo: Record) { diff --git a/app/client/src/types.ts b/app/client/src/types.ts index e9db911d7..c3185021f 100644 --- a/app/client/src/types.ts +++ b/app/client/src/types.ts @@ -10,6 +10,7 @@ export interface Isolate { amr?: AMR sketch?: string cluster?: number | string + lineage?: Dict } export interface Versions { @@ -37,7 +38,8 @@ export interface IsolateValue { } export enum AnalysisType { - ASSIGN = 'assign', + ASSIGNCLUSTERS = 'assignClusters', + ASSIGNLINEAGES = 'assignLineages', MICROREACT = 'microreact', NETWORK = 'network' } @@ -46,7 +48,7 @@ export type AnalysisStatus = { [key in AnalysisType]: string | null } -export type ClusterInfo = Dict> +export type ClusterInfo = Dict export interface BeebopError { error: string, From 17f7a3ae2f3cbc18c1673e45d9fddb95152f8801 Mon Sep 17 00:00:00 2001 From: muppi1993 Date: Fri, 18 Nov 2022 20:47:28 +0000 Subject: [PATCH 2/4] added route for lineage results --- app/server/src/routes/routes.ts | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/app/server/src/routes/routes.ts b/app/server/src/routes/routes.ts index 8bde9ef33..0a761044f 100644 --- a/app/server/src/routes/routes.ts +++ b/app/server/src/routes/routes.ts @@ -23,9 +23,13 @@ export const router = ((app, config) => { authCheck, api.getStatus); - app.post('/assignResult', + app.post('/assignClustersResult', authCheck, - api.getAssignResult); + api.getAssignClustersResult); + + app.post('/assignLineagesResult', + authCheck, + api.getAssignLineagesResult); app.get('/login/google', passport.authenticate('google', { scope: ['profile'] })); @@ -170,8 +174,22 @@ export const apiEndpoints = (config => ({ }); }, - async getAssignResult(request, response) { - await axios.post(`${config.api_url}/results/assign`, + async getAssignClustersResult(request, response) { + await axios.post(`${config.api_url}/results/assignClusters`, + request.body, + { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => response.send(res.data)) + .catch(function (error) { + sendError(response, error); + }); + }, + + async getAssignLineagesResult(request, response) { + await axios.post(`${config.api_url}/results/assignLineages`, request.body, { headers: { From bbc07ffde0044898af5f14eb5bc11666b958d8fa Mon Sep 17 00:00:00 2001 From: muppi1993 Date: Fri, 18 Nov 2022 20:48:10 +0000 Subject: [PATCH 3/4] adapted tests --- app/client/tests/e2e/LoggedIn.spec.ts | 8 +++ app/client/tests/mocks.ts | 2 +- .../tests/unit/components/ProgressBar.spec.ts | 16 +++-- .../unit/components/ResultsTable.spec.ts | 54 ++++++++++++---- app/client/tests/unit/store/actions.spec.ts | 64 ++++++++++++++----- app/client/tests/unit/store/getters.spec.ts | 9 +-- app/client/tests/unit/store/mutations.spec.ts | 34 +++++++++- app/client/tests/unit/views/HomeView.spec.ts | 10 +-- 8 files changed, 150 insertions(+), 47 deletions(-) diff --git a/app/client/tests/e2e/LoggedIn.spec.ts b/app/client/tests/e2e/LoggedIn.spec.ts index a8b02a6b8..1a17460d4 100644 --- a/app/client/tests/e2e/LoggedIn.spec.ts +++ b/app/client/tests/e2e/LoggedIn.spec.ts @@ -64,6 +64,14 @@ test.describe('Logged in Tests', () => { // Expect clusters appearing in table await expect(page.locator('tr:has-text("6930_8_13.fa")')).toContainText(['6930_8_13.fa', '✔', 'PCETE SXT', '7']); await expect(page.locator('tr:has-text("6930_8_11.fa")')).toContainText(['6930_8_11.fa', '✔', 'PCETE SXT', '24']); + // Expect lineages to appear in table + await expect(page.locator('tr:has-text("6930_8_13.fa")')).toContainText(['6930_8_13.fa', '✔', 'PCETE SXT', '7', '37']); + await expect(page.locator('tr:has-text("6930_8_11.fa")')).toContainText(['6930_8_11.fa', '✔', 'PCETE SXT', '24', '12']); + // Changing rank updates lineages + await page.click('text=Lineage Rank 1'); + await page.click('text=Rank 2'); + await expect(page.locator('tr:has-text("6930_8_13.fa")')).toContainText(['6930_8_13.fa', '✔', 'PCETE SXT', '7', '6']); + await expect(page.locator('tr:has-text("6930_8_11.fa")')).toContainText(['6930_8_11.fa', '✔', 'PCETE SXT', '24', '2']); // Expect download buttons and button to generate microreact URL to appear await expect(page.locator('tr:has-text("6930_8_13.fa") .btn').nth(0)).toContainText('Download zip file'); await expect(page.locator('tr:has-text("6930_8_13.fa") .btn').nth(1)).toContainText('Generate Microreact URL'); diff --git a/app/client/tests/mocks.ts b/app/client/tests/mocks.ts index 36b4ff267..62cda8ce3 100644 --- a/app/client/tests/mocks.ts +++ b/app/client/tests/mocks.ts @@ -19,7 +19,7 @@ export function mockRootState(state: Partial = {}): RootState { }, submitStatus: null, analysisStatus: { - assign: null, microreact: null, network: null, + assignClusters: null, assignLineages: null, microreact: null, network: null, }, statusInterval: undefined, projectHash: null, diff --git a/app/client/tests/unit/components/ProgressBar.spec.ts b/app/client/tests/unit/components/ProgressBar.spec.ts index 204dd7a9e..6fa204106 100644 --- a/app/client/tests/unit/components/ProgressBar.spec.ts +++ b/app/client/tests/unit/components/ProgressBar.spec.ts @@ -7,14 +7,15 @@ import { mockRootState } from '../../mocks'; describe('Progress bar', () => { const analysisProgress = jest.fn().mockReturnValue({ finished: 1, - progress: 0.3333333333333333, - total: 3, + progress: 0.25, + total: 4, }); const store = new Vuex.Store({ state: mockRootState({ analysisStatus: { - assign: 'finished', + assignClusters: 'finished', + assignLineages: 'queued', microreact: 'queued', network: 'started', }, @@ -37,21 +38,22 @@ describe('Progress bar', () => { it('gets analysisProgress and displays status', () => { expect(analysisProgress).toHaveBeenCalledTimes(1); expect(wrapper.vm.animated).toBe(true); - expect(wrapper.find('.progress-bar').text()).toBe('33.33%'); + expect(wrapper.find('.progress-bar').text()).toBe('25.00%'); }); }); describe('Progress bar finished', () => { const analysisProgress = jest.fn().mockReturnValue({ - finished: 3, + finished: 4, progress: 1, - total: 3, + total: 4, }); const store = new Vuex.Store({ state: mockRootState({ analysisStatus: { - assign: 'finished', + assignClusters: 'finished', + assignLineages: 'finished', microreact: 'finished', network: 'finished', }, diff --git a/app/client/tests/unit/components/ResultsTable.spec.ts b/app/client/tests/unit/components/ResultsTable.spec.ts index d5ab3a1dd..86251b74c 100644 --- a/app/client/tests/unit/components/ResultsTable.spec.ts +++ b/app/client/tests/unit/components/ResultsTable.spec.ts @@ -15,7 +15,8 @@ describe('ResultsTable complete', () => { }, submitStatus: 'submitted', analysisStatus: { - assign: 'finished', + assignClusters: 'finished', + assignLineages: 'finished', microreact: 'finished', network: 'finished', }, @@ -26,6 +27,11 @@ describe('ResultsTable complete', () => { filename: 'example1.fa', sketch: 'sketch', cluster: 7, + lineage: { + rank1: "12", + rank2: "3", + rank3: "2", + }, amr: { filename: 'example1.fa', Penicillin: 0.892, @@ -40,6 +46,11 @@ describe('ResultsTable complete', () => { filename: 'example2.fa', sketch: 'sketch', cluster: 3, + lineage: { + rank1: "7", + rank2: "2", + rank3: "2", + }, amr: { filename: 'example2.fa', Penicillin: 0.892, @@ -54,6 +65,11 @@ describe('ResultsTable complete', () => { filename: 'example3.fa', sketch: 'sketch', cluster: 7, + lineage: { + rank1: "15", + rank2: "4", + rank3: "2", + }, amr: { filename: 'example3.fa', Penicillin: 0.892, @@ -94,6 +110,7 @@ describe('ResultsTable complete', () => { Trim_sulfa: 0.974, }, Cluster: 3, + Lineage: '7', Microreact: 'showButton', Network: 'showButton', Rowspan: 1, @@ -111,6 +128,7 @@ describe('ResultsTable complete', () => { Trim_sulfa: 0.974, }, Cluster: 7, + Lineage: '12', Microreact: 'showButton', Network: 'showButton', Rowspan: 2, @@ -128,6 +146,7 @@ describe('ResultsTable complete', () => { Trim_sulfa: 0.974, }, Cluster: 7, + Lineage: '15', Microreact: 'showButton', Network: 'showButton', Rowspan: 0, @@ -150,25 +169,34 @@ describe('ResultsTable complete', () => { test('results are displayed in the table', () => { // 6 headers exist const headers = wrapper.findAll('th'); - expect(headers.length).toBe(6); + expect(headers.length).toBe(7); // 3 rows exist const rows = wrapper.findAll('tr'); expect(rows.length).toBe(3); // 16 cells exist (3x6 minus two merged cells) const cells = wrapper.findAll('td'); - expect(cells.length).toBe(16); + expect(cells.length).toBe(19); // first cell in each row displays filenames expect(cells[0].text()).toBe('example2.fa'); - expect(cells[6].text()).toBe('example1.fa'); - expect(cells[12].text()).toBe('example3.fa'); + expect(cells[7].text()).toBe('example1.fa'); + expect(cells[14].text()).toBe('example3.fa'); // microreact & network cells from same cluster are merged - expect(cells[10].attributes('rowspan')).toBe('2'); - expect(cells[11].attributes('rowspan')).toBe('2'); + expect(cells[12].attributes('rowspan')).toBe('2'); + expect(cells[13].attributes('rowspan')).toBe('2'); // AMR cells have tooltip const amrCells = wrapper.findAll('span'); expect(amrCells.length).toBe(3); expect(amrCells[0].attributes('data-bs-original-title')).toBe(mockTooltipText); }); + + test('selecting another rank from lineage dropdown menu changes lineages', async () => { + const cells = wrapper.findAll('td'); + expect(cells[4].text()).toBe('7'); + expect(wrapper.findAll('.dropdown-item')).toHaveLength(3); + await wrapper.find('#two').trigger('click'); + expect(wrapper.vm.rank).toBe(2); + expect(cells[4].text()).toBe('2'); + }); }); describe('ResultsTable incomplete', () => { @@ -181,7 +209,8 @@ describe('ResultsTable incomplete', () => { }, submitStatus: 'submitted', analysisStatus: { - assign: 'started', + assignClusters: 'started', + assignLineages: 'waiting', microreact: 'waiting', network: 'waiting', }, @@ -241,14 +270,15 @@ describe('ResultsTable incomplete', () => { test('results are displayed in the table', () => { const cells = wrapper.findAll('td'); // cells not yet merged - expect(cells.length).toBe(18); + expect(cells.length).toBe(21); // filenames not yet sorted by cluster expect(cells[0].text()).toBe('example1.fa'); - expect(cells[6].text()).toBe('example2.fa'); - expect(cells[12].text()).toBe('example3.fa'); - // cluster, microreact and network cells show analysis status + expect(cells[7].text()).toBe('example2.fa'); + expect(cells[14].text()).toBe('example3.fa'); + // cluster, lineage, microreact and network cells show analysis status expect(cells[3].text()).toBe('started'); expect(cells[4].text()).toBe('waiting'); expect(cells[5].text()).toBe('waiting'); + expect(cells[6].text()).toBe('waiting'); }); }); diff --git a/app/client/tests/unit/store/actions.spec.ts b/app/client/tests/unit/store/actions.spec.ts index d8c4926c0..de8b2ff84 100644 --- a/app/client/tests/unit/store/actions.spec.ts +++ b/app/client/tests/unit/store/actions.spec.ts @@ -99,7 +99,7 @@ describe('Actions', () => { }); const expectedHash = Md5.hashStr('someFileHashsomeFilenamesomeFileHash2someFilename2'); mockAxios.onPost(`${serverUrl}/poppunk`).reply(200, responseSuccess({ - assign: 'job-id', microreact: 'job-id', network: 'job-id', + assignClusters: 'job-id', assignLineages: 'job-id', microreact: 'job-id', network: 'job-id', })); await actions.runPoppunk({ commit, state } as any); expect(mockAxios.history.post[0].url).toEqual(`${serverUrl}/poppunk`); @@ -109,26 +109,28 @@ describe('Actions', () => { expect(commit.mock.calls[1]).toEqual([ 'setAnalysisStatus', { - assign: 'submitted', + assignClusters: 'submitted', + assignLineages: 'submitted', microreact: 'submitted', network: 'submitted', }]); }); - it('getStatus makes axios call and updates analysisStatus, triggers getAssignResult', async () => { + it('getStatus makes axios call and updates analysisStatus, triggers getAssignClustersResult', async () => { const commit = jest.fn(); const dispatch = jest.fn(); const state = mockRootState({ projectHash: 'randomHash', submitStatus: 'submitted', analysisStatus: { - assign: 'started', + assignClusters: 'started', + assignLineages: 'waiting', microreact: 'waiting', network: 'waiting', }, }); mockAxios.onPost(`${serverUrl}/status`).reply(200, responseSuccess({ - assign: 'finished', microreact: 'started', network: 'queued', + assignClusters: 'finished', assignLineages: 'queued', microreact: 'started', network: 'queued', })); await actions.getStatus({ commit, state, dispatch } as any); expect(mockAxios.history.post[0].url).toEqual(`${serverUrl}/status`); @@ -137,11 +139,12 @@ describe('Actions', () => { { microreact: 'started', network: 'queued', - assign: 'finished', + assignClusters: 'finished', + assignLineages: 'queued', }, ]); expect(dispatch).toHaveBeenCalledTimes(1); - expect(dispatch).toHaveBeenCalledWith('getAssignResult'); + expect(dispatch).toHaveBeenCalledWith('getAssignClustersResult'); }); it('getStatus stops updating analysisStatus once all jobs finished', async () => { @@ -153,14 +156,15 @@ describe('Actions', () => { projectHash: 'randomHash', submitStatus: 'submitted', analysisStatus: { - assign: 'finished', + assignClusters: 'finished', + assignLineages: 'queued', microreact: 'started', network: 'queued', }, statusInterval: 202, }); mockAxios.onPost(`${serverUrl}/status`).reply(200, responseSuccess({ - assign: 'finished', microreact: 'finished', network: 'finished', + assignClusters: 'finished', assignLineages: 'finished', microreact: 'finished', network: 'finished', })); await actions.getStatus({ commit, state, dispatch } as any); expect(clearInterval).toHaveBeenCalledTimes(1); @@ -178,14 +182,15 @@ describe('Actions', () => { projectHash: 'randomHash', submitStatus: 'submitted', analysisStatus: { - assign: 'finished', + assignClusters: 'finished', + assignLineages: 'finished', microreact: 'started', network: 'queued', }, statusInterval: 202, }); mockAxios.onPost(`${serverUrl}/status`).reply(200, responseSuccess({ - assign: 'finished', microreact: 'failed', network: 'failed', + assignClusters: 'finished', assignLineages: 'finished', microreact: 'failed', network: 'failed', })); await actions.getStatus({ commit, state, dispatch } as any); expect(clearInterval).toHaveBeenCalledTimes(1); @@ -203,7 +208,8 @@ describe('Actions', () => { projectHash: 'randomHash', submitStatus: 'submitted', analysisStatus: { - assign: 'submitted', + assignClusters: 'submitted', + assignLineages: 'submitted', microreact: 'submitted', network: 'submitted', }, @@ -225,7 +231,7 @@ describe('Actions', () => { expect(commit.mock.calls[0][1]).toEqual(expect.any(Number)); }); - it('getAssignResult makes axios call and updates clusters', async () => { + it('getAssignClustersResult makes axios call and updates clusters', async () => { const commit = jest.fn(); const state = mockRootState({ projectHash: 'randomHash', @@ -242,15 +248,41 @@ describe('Actions', () => { }, }); const expResponse = responseSuccess({ 0: { hash: 'someFileHash', cluster: '12' }, 1: { hash: 'someFileHash2', cluster: '2' } }); - mockAxios.onPost(`${serverUrl}/assignResult`).reply(200, expResponse); - await actions.getAssignResult({ commit, state } as any); - expect(mockAxios.history.post[0].url).toEqual(`${serverUrl}/assignResult`); + mockAxios.onPost(`${serverUrl}/assignClustersResult`).reply(200, expResponse); + await actions.getAssignClustersResult({ commit, state } as any); + expect(mockAxios.history.post[0].url).toEqual(`${serverUrl}/assignClustersResult`); expect(commit.mock.calls[0]).toEqual([ 'setClusters', expResponse.data, ]); }); + it('getAssignLineagesResult makes axios call and updates clusters', async () => { + const commit = jest.fn(); + const state = mockRootState({ + projectHash: 'randomHash', + results: { + perIsolate: { + someFileHash: { + hash: 'someFileHash', + }, + someFileHash2: { + hash: 'someFileHash2', + }, + }, + perCluster: {}, + }, + }); + const expResponse = responseSuccess({ 0: { hash: 'someFileHash', cluster: '12' }, 1: { hash: 'someFileHash2', cluster: '2' } }); + mockAxios.onPost(`${serverUrl}/assignLineagesResult`).reply(200, expResponse); + await actions.getAssignLineagesResult({ commit, state } as any); + expect(mockAxios.history.post[0].url).toEqual(`${serverUrl}/assignLineagesResult`); + expect(commit.mock.calls[0]).toEqual([ + 'setLineages', + expResponse.data, + ]); + }); + it('submitData triggers runPoppunk, startStatusPolling and sets submitStatus', async () => { const commit = jest.fn(); const dispatch = jest.fn(); diff --git a/app/client/tests/unit/store/getters.spec.ts b/app/client/tests/unit/store/getters.spec.ts index 87610aada..22b90383b 100644 --- a/app/client/tests/unit/store/getters.spec.ts +++ b/app/client/tests/unit/store/getters.spec.ts @@ -7,15 +7,16 @@ describe('getters', () => { projectHash: 'randomHash', submitStatus: 'submitted', analysisStatus: { - assign: 'finished', + assignClusters: 'finished', + assignLineages: 'finished', microreact: 'started', network: 'queued', }, }); expect(getters.analysisProgress(state, 'analysisProgress', state, 'analysisProgress')).toStrictEqual({ - finished: 1, - progress: 0.3333333333333333, - total: 3, + finished: 2, + progress: 0.5, + total: 4, }); }); it('gets unique clusters', () => { diff --git a/app/client/tests/unit/store/mutations.spec.ts b/app/client/tests/unit/store/mutations.spec.ts index 548c7593f..924bb01cd 100644 --- a/app/client/tests/unit/store/mutations.spec.ts +++ b/app/client/tests/unit/store/mutations.spec.ts @@ -92,7 +92,8 @@ describe('mutations', () => { it('sets analysisStatus', () => { const state = mockRootState(); const statusUpdate = { - assign: 'finished', + assignClusters: 'finished', + assignLineages: 'finished', microreact: 'started', network: 'queued', }; @@ -125,9 +126,38 @@ describe('mutations', () => { perCluster: {}, }, }); - mutations.setClusters(state, { 0: { hash: 'someFileHash', cluster: '12' }, 1: { hash: 'someFileHash2', cluster: '2' } }); + mutations.setClusters(state, { 12: ['someFileHash'], 1: ['someFileHash2'] }); expect(state.results.perIsolate.someFileHash.cluster).toBe('12'); }); + it('sets lineages', () => { + const state = mockRootState({ + results: { + perIsolate: { + someFileHash: { + hash: 'someFileHash', + }, + someFileHash2: { + hash: 'someFileHash2', + }, + }, + perCluster: {}, + }, + }); + mutations.setLineages(state, { 'someFileHash': { + rank1: "12", + rank2: "3", + rank3: "2", + }, 'someFileHash2': { + rank1: "15", + rank2: "4", + rank3: "2", + }}); + expect(state.results.perIsolate.someFileHash.lineage).toStrictEqual({ + rank1: "12", + rank2: "3", + rank3: "2", + }); + }); it('sets MicroreactURL', () => { const state = mockRootState(); const mockURLInfo = { diff --git a/app/client/tests/unit/views/HomeView.spec.ts b/app/client/tests/unit/views/HomeView.spec.ts index 2b84e2cf9..ef28df737 100644 --- a/app/client/tests/unit/views/HomeView.spec.ts +++ b/app/client/tests/unit/views/HomeView.spec.ts @@ -96,7 +96,7 @@ describe('Home', () => { }, submitStatus: null, analysisStatus: { - assign: null, microreact: null, network: null, + assignClusters: null, assignLineages: null, microreact: null, network: null, }, }), actions: { @@ -116,8 +116,8 @@ describe('Home', () => { it('shows status bar when data was submitted to backend', () => { const analysisProgress = jest.fn().mockReturnValue({ finished: 1, - progress: 0.3333333333333333, - total: 3, + progress: 0.25, + total: 4, }); const store = new Vuex.Store({ state: mockRootState({ @@ -135,7 +135,7 @@ describe('Home', () => { }, submitStatus: 'submitted', analysisStatus: { - assign: 'finished', microreact: 'started', network: 'queued', + assignClusters: 'finished', assignLineages: 'queued', microreact: 'started', network: 'queued', }, }), actions: { @@ -153,6 +153,6 @@ describe('Home', () => { const statusBar = wrapper.findAll('.progress'); expect(analysisProgress).toHaveBeenCalled(); expect(statusBar.length).toBe(1); - expect(statusBar[0].text()).toBe('33.33%'); // Nan + expect(statusBar[0].text()).toBe('25.00%'); // Nan }); }); From d359c4c06d3d02f2b3c96a004532a89c509cb7ad Mon Sep 17 00:00:00 2001 From: muppi1993 Date: Fri, 18 Nov 2022 20:48:56 +0000 Subject: [PATCH 4/4] updated backend version --- scripts/run_test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_test b/scripts/run_test index 63ae74f67..b7eb01559 100755 --- a/scripts/run_test +++ b/scripts/run_test @@ -4,7 +4,7 @@ NETWORK=beebop_nw VOLUME=beebop-storage NAME_REDIS=beebop-redis NAME_API=beebop-py-api -API_BRANCH=bacpop-61 +API_BRANCH=bacpop-71 NAME_WORKER=beebop-py-worker PORT=5000