From 6514f7f0136c4a8513a0f36936fec0b7108a3a82 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Fri, 7 Jun 2024 18:05:52 +0200 Subject: [PATCH 1/7] Render public virtual studies as a separate section --- .../api/session-service/sessionServiceAPI.ts | 20 +++++++++++ .../components/query/CancerStudyTreeData.ts | 36 +++++++++++++++++++ src/shared/components/query/QueryStore.ts | 16 +++++++++ .../components/query/studyList/StudyList.tsx | 6 +++- 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/shared/api/session-service/sessionServiceAPI.ts b/src/shared/api/session-service/sessionServiceAPI.ts index 0b429dfa430..898fd36f936 100644 --- a/src/shared/api/session-service/sessionServiceAPI.ts +++ b/src/shared/api/session-service/sessionServiceAPI.ts @@ -17,6 +17,14 @@ export default class sessionServiceAPI { return `${getSessionUrl()}/virtual_study`; } + getPublicVirtualStudyServiceUrl() { + //FIXME change url after moving the code to the session controller + return getSessionUrl().replace( + 'api/session', + 'api/public_virtual_studies' + ); + } + getSessionServiceUrl() { return `${getSessionUrl()}/main_session`; } @@ -44,6 +52,18 @@ export default class sessionServiceAPI { ); } + getPublicVirtualStudies(): Promise> { + return ( + request + .get(this.getPublicVirtualStudyServiceUrl()) + // @ts-ignore: this method comes from caching plugin and isn't in typing + .forceUpdate(true) + .then((res: any) => { + return res.body; + }) + ); + } + getVirtualStudy(id: string): Promise { return ( request diff --git a/src/shared/components/query/CancerStudyTreeData.ts b/src/shared/components/query/CancerStudyTreeData.ts index ceadae2589f..caa3f06d77e 100644 --- a/src/shared/components/query/CancerStudyTreeData.ts +++ b/src/shared/components/query/CancerStudyTreeData.ts @@ -8,6 +8,7 @@ import { VirtualStudy } from 'shared/api/session-service/sessionServiceModels'; export const CANCER_TYPE_ROOT = 'tissue'; export const VIRTUAL_STUDY_NAME = 'My Virtual Studies'; +export const PUBLIC_VIRTUAL_STUDY_NAME = 'Public Virtual Studies'; export const PHYSICAL_STUDY_NAME = 'Studies'; export type CancerTypeWithVisibility = CancerType & { @@ -63,6 +64,16 @@ export default class CancerStudyTreeData { alwaysVisible: true, }; + publicVirtualStudyCategory: CancerTypeWithVisibility = { + id: 'public_virtual_studies_list', + dedicatedColor: '', + name: PUBLIC_VIRTUAL_STUDY_NAME, + parent: CANCER_TYPE_ROOT, + shortName: PUBLIC_VIRTUAL_STUDY_NAME, + cancerTypeId: PUBLIC_VIRTUAL_STUDY_NAME, + alwaysVisible: true, + }; + physicalStudyCategory: CancerTypeWithVisibility = { dedicatedColor: '', name: PHYSICAL_STUDY_NAME, @@ -83,6 +94,7 @@ export default class CancerStudyTreeData { allStudyTags = [], priorityStudies = {}, virtualStudies = [], + publicVirtualStudies = [], maxTreeDepth = 0, }: { cancerTypes: CancerTypeWithVisibility[]; @@ -90,6 +102,7 @@ export default class CancerStudyTreeData { allStudyTags: StudyTags[]; priorityStudies?: CategorizedConfigItems; virtualStudies?: VirtualStudy[]; + publicVirtualStudies?: VirtualStudy[]; maxTreeDepth: number; }) { let nodes: CancerTreeNode[]; @@ -99,6 +112,27 @@ export default class CancerStudyTreeData { // sort by name cancerTypes = CancerStudyTreeData.sortNodes(cancerTypes); + //map public virtual study to cancer study + const _publicVirtualStudies = publicVirtualStudies + .map(publicVirtualStudy => { + // TODO: temp fix for when virtual study data is not of expeceted format + // (e.g. old format) Might need some better sanity checking of + // virtual/session data + if (publicVirtualStudy.data) { + return { + allSampleCount: _.sumBy( + publicVirtualStudy.data.studies, + study => study.samples.length + ), + studyId: publicVirtualStudy.id, + name: publicVirtualStudy.data.name, + description: publicVirtualStudy.data.description, + cancerTypeId: PUBLIC_VIRTUAL_STUDY_NAME, + } as CancerStudy; + } + }) + .filter(publicVirtualStudy => publicVirtualStudy) as CancerStudy[]; + //map virtual study to cancer study const _virtualStudies = virtualStudies .map(virtualstudy => { @@ -140,6 +174,7 @@ export default class CancerStudyTreeData { } // add virtual study category, and studies cancerTypes = [ + this.publicVirtualStudyCategory, this.virtualStudyCategory, this.physicalStudyCategory, ...this.priorityCategories, @@ -147,6 +182,7 @@ export default class CancerStudyTreeData { ...cancerTypes, ]; studies = CancerStudyTreeData.sortNodes([ + ..._publicVirtualStudies, ..._virtualStudies, ...studies, ]); diff --git a/src/shared/components/query/QueryStore.ts b/src/shared/components/query/QueryStore.ts index 30164aed980..1ba2ba15502 100644 --- a/src/shared/components/query/QueryStore.ts +++ b/src/shared/components/query/QueryStore.ts @@ -792,6 +792,19 @@ export class QueryStore { } }, []); + readonly publicVirtualStudies = remoteData(async () => { + if (ServerConfigHelpers.sessionServiceIsEnabled()) { + try { + const studies = await sessionServiceClient.getPublicVirtualStudies(); + return studies; + } catch (ex) { + return []; + } + } else { + return []; + } + }, []); + private readonly userVirtualStudiesSet = remoteData<{ [studyId: string]: VirtualStudy; }>({ @@ -1490,6 +1503,9 @@ export class QueryStore { virtualStudies: this.forDownloadTab ? [] : this.userVirtualStudies.result, + publicVirtualStudies: this.forDownloadTab + ? [] + : this.publicVirtualStudies.result, maxTreeDepth: this.maxTreeDepth, }); } diff --git a/src/shared/components/query/studyList/StudyList.tsx b/src/shared/components/query/studyList/StudyList.tsx index b84244a39d8..632b993cc1a 100644 --- a/src/shared/components/query/studyList/StudyList.tsx +++ b/src/shared/components/query/studyList/StudyList.tsx @@ -14,6 +14,7 @@ import { FilteredCancerTreeView } from '../StudyListLogic'; import { CancerTreeNode, CancerTypeWithVisibility, + PUBLIC_VIRTUAL_STUDY_NAME, } from '../CancerStudyTreeData'; import { StudyLink } from '../../StudyLink/StudyLink'; import StudyTagsTooltip, { @@ -303,7 +304,10 @@ export default class StudyList extends QueryStoreComponent< }, ]; - if (this.store.isVirtualStudy(study.studyId)) { + if ( + this.store.isVirtualStudy(study.studyId) && + study.cancerTypeId != PUBLIC_VIRTUAL_STUDY_NAME + ) { links.push({ icon: 'trash', tooltip: 'Delete this virtual study.', From fa0b5e69da6ebdfea9e01a0e1eaa1174689ec098 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Wed, 12 Jun 2024 18:05:14 +0200 Subject: [PATCH 2/7] Use public virtual study metadata to blend it in regular studies --- .../session-service/sessionServiceModels.ts | 2 + .../components/query/CancerStudyTreeData.ts | 5 +- src/shared/components/query/QueryStore.ts | 52 +++++++++++++++++-- .../components/query/studyList/StudyList.tsx | 2 +- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/shared/api/session-service/sessionServiceModels.ts b/src/shared/api/session-service/sessionServiceModels.ts index 89eae2248e5..01d85333b5b 100644 --- a/src/shared/api/session-service/sessionServiceModels.ts +++ b/src/shared/api/session-service/sessionServiceModels.ts @@ -33,6 +33,8 @@ export interface VirtualStudyData { studies: { id: string; samples: string[] }[]; origin: string[]; studyViewFilter: StudyViewFilter; + typeOfCancerId?: string; + pmid?: string; } export type GroupData = Omit; diff --git a/src/shared/components/query/CancerStudyTreeData.ts b/src/shared/components/query/CancerStudyTreeData.ts index caa3f06d77e..e1f834caff8 100644 --- a/src/shared/components/query/CancerStudyTreeData.ts +++ b/src/shared/components/query/CancerStudyTreeData.ts @@ -127,7 +127,10 @@ export default class CancerStudyTreeData { studyId: publicVirtualStudy.id, name: publicVirtualStudy.data.name, description: publicVirtualStudy.data.description, - cancerTypeId: PUBLIC_VIRTUAL_STUDY_NAME, + cancerTypeId: + publicVirtualStudy.data.typeOfCancerId || + PUBLIC_VIRTUAL_STUDY_NAME, + pmid: publicVirtualStudy.data.pmid, } as CancerStudy; } }) diff --git a/src/shared/components/query/QueryStore.ts b/src/shared/components/query/QueryStore.ts index 1ba2ba15502..13e878d188b 100644 --- a/src/shared/components/query/QueryStore.ts +++ b/src/shared/components/query/QueryStore.ts @@ -225,7 +225,13 @@ export class QueryStore { } @computed get virtualStudiesMap(): { [id: string]: VirtualStudy } { - return _.keyBy(this.userVirtualStudies.result, study => study.id); + return _.keyBy( + [ + ...this.userVirtualStudies.result, + ...this.publicVirtualStudies.result, + ], + study => study.id + ); } @computed get selectedVirtualStudies(): VirtualStudy[] { @@ -821,18 +827,40 @@ export class QueryStore { default: {}, }); + private readonly publicVirtualStudiesSet = remoteData<{ + [studyId: string]: VirtualStudy; + }>({ + await: () => [this.publicVirtualStudies], + invoke: async () => { + return this.publicVirtualStudies.result.reduce( + (obj: { [studyId: string]: VirtualStudy }, item) => { + obj[item.id] = item; + return obj; + }, + {} + ); + }, + default: {}, + }); + private readonly sharedVirtualStudiesSet = remoteData<{ [studyId: string]: VirtualStudy; }>({ - await: () => [this.physicalStudiesSet, this.userVirtualStudiesSet], + await: () => [ + this.physicalStudiesSet, + this.userVirtualStudiesSet, + this.publicVirtualStudiesSet, + ], invoke: async () => { let physicalStudiesIdsSet = this.physicalStudiesSet.result; let virtualStudiesIdsSet = this.userVirtualStudiesSet.result; + let publicStudiesIdsSet = this.publicVirtualStudiesSet.result; let knownSelectableIds = Object.assign( [], Object.keys(physicalStudiesIdsSet), - Object.keys(virtualStudiesIdsSet) + Object.keys(virtualStudiesIdsSet), + Object.keys(publicStudiesIdsSet) ); //queried id that are not selectable(this would mostly be shared virtual study) @@ -877,12 +905,15 @@ export class QueryStore { private readonly selectedStudyToSampleSet = remoteData<{ [id: string]: { [id: string]: boolean }; }>({ - await: () => [this.userVirtualStudiesSet, this.sharedVirtualStudiesSet], + await: () => [ + this.userVirtualStudiesSet, + this.sharedVirtualStudiesSet, + this.publicVirtualStudiesSet, + ], invoke: async () => { let studyToSampleSet: { [id: string]: { [id: string]: boolean }; } = {}; - const physicalStudyIds = _.filter( this.allSelectedStudyIds, studyId => this.physicalStudiesSet.result[studyId] @@ -906,6 +937,7 @@ export class QueryStore { const _vs = { ...this.userVirtualStudiesSet.result, ...this.sharedVirtualStudiesSet.result, + ...this.publicVirtualStudiesSet.result, }; for (const id of this._allSelectedStudyIds.keys()) { @@ -958,6 +990,12 @@ export class QueryStore { ); } ); + _.each( + this.publicVirtualStudiesSet.result, + (virtualStudy, studyId) => { + result[studyId] = [studyId]; + } + ); return result; }, @@ -1545,6 +1583,10 @@ export class QueryStore { return !this.cancerStudyIdsSet.result[studyId]; } + public isPublicVirtualStudy(studyId: string): boolean { + return !!this.publicVirtualStudies.result.find(ps => ps.id == studyId); + } + public isDeletedVirtualStudy(studyId: string): boolean { if ( this.isVirtualStudy(studyId) && diff --git a/src/shared/components/query/studyList/StudyList.tsx b/src/shared/components/query/studyList/StudyList.tsx index 632b993cc1a..dcd87be0dcf 100644 --- a/src/shared/components/query/studyList/StudyList.tsx +++ b/src/shared/components/query/studyList/StudyList.tsx @@ -306,7 +306,7 @@ export default class StudyList extends QueryStoreComponent< if ( this.store.isVirtualStudy(study.studyId) && - study.cancerTypeId != PUBLIC_VIRTUAL_STUDY_NAME + !this.store.isPublicVirtualStudy(study.studyId) ) { links.push({ icon: 'trash', From 913e9545509dcf9d407e14904374f5159f3f7793 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Tue, 9 Jul 2024 16:31:05 +0200 Subject: [PATCH 3/7] Remove code smell Parametrise public vs url instead of replacing it in a result url --- src/shared/api/session-service/sessionServiceAPI.ts | 6 +----- src/shared/api/urls.ts | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/shared/api/session-service/sessionServiceAPI.ts b/src/shared/api/session-service/sessionServiceAPI.ts index 898fd36f936..8db41ce361f 100644 --- a/src/shared/api/session-service/sessionServiceAPI.ts +++ b/src/shared/api/session-service/sessionServiceAPI.ts @@ -18,11 +18,7 @@ export default class sessionServiceAPI { } getPublicVirtualStudyServiceUrl() { - //FIXME change url after moving the code to the session controller - return getSessionUrl().replace( - 'api/session', - 'api/public_virtual_studies' - ); + return getSessionUrl('api/public_virtual_studies'); } getSessionServiceUrl() { diff --git a/src/shared/api/urls.ts b/src/shared/api/urls.ts index 8aaddbbff41..b54dd9179ea 100644 --- a/src/shared/api/urls.ts +++ b/src/shared/api/urls.ts @@ -245,14 +245,14 @@ export function getGenomeNexusHgvsgUrl( : `${getServerConfig().genomenexus_website_url}/variant/${hgvsg}`; } -export function getSessionUrl() { +export function getSessionUrl(path = 'api/session') { if (getServerConfig() && getServerConfig().hasOwnProperty('apiRoot')) { // TODO: remove this after switch to AWS. This is a hack to use proxy // session-service from non apiRoot. We'll have to come up with a better // solution for auth portals - return buildCBioPortalPageUrl('api/session'); + return buildCBioPortalPageUrl(path); } else { - return buildCBioPortalAPIUrl('api/session'); + return buildCBioPortalAPIUrl(path); } } From b0cb7cd0d62a233c0e6ed8c0c24a5f0a9106161a Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Tue, 9 Jul 2024 16:44:52 +0200 Subject: [PATCH 4/7] Remove copy pasted for public VS legacy code Public VS functionality won't even work for legacy VS json format --- .../components/query/CancerStudyTreeData.ts | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/shared/components/query/CancerStudyTreeData.ts b/src/shared/components/query/CancerStudyTreeData.ts index e1f834caff8..4ec67c7090d 100644 --- a/src/shared/components/query/CancerStudyTreeData.ts +++ b/src/shared/components/query/CancerStudyTreeData.ts @@ -113,28 +113,23 @@ export default class CancerStudyTreeData { cancerTypes = CancerStudyTreeData.sortNodes(cancerTypes); //map public virtual study to cancer study - const _publicVirtualStudies = publicVirtualStudies - .map(publicVirtualStudy => { - // TODO: temp fix for when virtual study data is not of expeceted format - // (e.g. old format) Might need some better sanity checking of - // virtual/session data - if (publicVirtualStudy.data) { - return { - allSampleCount: _.sumBy( - publicVirtualStudy.data.studies, - study => study.samples.length - ), - studyId: publicVirtualStudy.id, - name: publicVirtualStudy.data.name, - description: publicVirtualStudy.data.description, - cancerTypeId: - publicVirtualStudy.data.typeOfCancerId || - PUBLIC_VIRTUAL_STUDY_NAME, - pmid: publicVirtualStudy.data.pmid, - } as CancerStudy; - } - }) - .filter(publicVirtualStudy => publicVirtualStudy) as CancerStudy[]; + const _publicVirtualStudies = publicVirtualStudies.map( + publicVirtualStudy => { + return { + allSampleCount: _.sumBy( + publicVirtualStudy.data.studies, + study => study.samples.length + ), + studyId: publicVirtualStudy.id, + name: publicVirtualStudy.data.name, + description: publicVirtualStudy.data.description, + cancerTypeId: + publicVirtualStudy.data.typeOfCancerId || + PUBLIC_VIRTUAL_STUDY_NAME, + pmid: publicVirtualStudy.data.pmid, + } as CancerStudy; + } + ); //map virtual study to cancer study const _virtualStudies = virtualStudies From ea4f694263ee0f4855d99f49a3e0ce403bee45e8 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Tue, 9 Jul 2024 16:48:54 +0200 Subject: [PATCH 5/7] Remove not used import statement --- src/shared/components/query/studyList/StudyList.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/shared/components/query/studyList/StudyList.tsx b/src/shared/components/query/studyList/StudyList.tsx index dcd87be0dcf..7cd975d062e 100644 --- a/src/shared/components/query/studyList/StudyList.tsx +++ b/src/shared/components/query/studyList/StudyList.tsx @@ -14,7 +14,6 @@ import { FilteredCancerTreeView } from '../StudyListLogic'; import { CancerTreeNode, CancerTypeWithVisibility, - PUBLIC_VIRTUAL_STUDY_NAME, } from '../CancerStudyTreeData'; import { StudyLink } from '../../StudyLink/StudyLink'; import StudyTagsTooltip, { From f28e5a08c18e07bf9f93ee810e2d42bb2cda5c75 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Mon, 15 Jul 2024 15:25:00 +0200 Subject: [PATCH 6/7] Add e2e tests for private VS --- .../local/specs/virtual-study.spec.js | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 end-to-end-test/local/specs/virtual-study.spec.js diff --git a/end-to-end-test/local/specs/virtual-study.spec.js b/end-to-end-test/local/specs/virtual-study.spec.js new file mode 100644 index 00000000000..1383d3661de --- /dev/null +++ b/end-to-end-test/local/specs/virtual-study.spec.js @@ -0,0 +1,59 @@ +var assert = require('assert'); +var goToUrlAndSetLocalStorage = require('../../shared/specUtils') + .goToUrlAndSetLocalStorage; + +const CBIOPORTAL_URL = process.env.CBIOPORTAL_URL.replace(/\/$/, ''); +const studyEs0Summary = CBIOPORTAL_URL + '/study/summary?id=study_es_0'; + +describe('Virtual Study life cycle', function() { + const vsTitle = 'Test VS ' + Date.now(); + it('Login and navigate to the study_es_0 study summary page', function() { + goToUrlAndSetLocalStorage(studyEs0Summary, true); + }); + it('Click Share Virtual Study button', function() { + const studyView = $('.studyView'); + const shareVSBtn = studyView.$( + 'button[data-tour="action-button-bookmark"]' + ); + shareVSBtn.waitForClickable(); + shareVSBtn.click(); + }); + it('Provid the title and save', function() { + const modalDialog = $('.modal-dialog'); + modalDialog.waitForDisplayed(); + const titleInput = modalDialog.$('input#sniglet'); + titleInput.setValue(vsTitle); + const saveBtn = modalDialog.$( + '[data-tour="virtual-study-summary-save-btn"]' + ); + saveBtn.click(); + modalDialog.$('.text-success').waitForDisplayed(); + const linkInput = modalDialog.$('input[type="text"]'); + const link = linkInput.getValue(); + assert.ok( + link.startsWith('http'), + 'The value should be link, but was ' + link + ); + }); + it('See the VS in My Virtual Studies section on the landing page', function() { + goToUrlAndSetLocalStorage(CBIOPORTAL_URL, true); + const myVirtualStudies = $( + '//*[text()="My Virtual Studies"]/ancestor::ul[1]' + ); + myVirtualStudies.waitForDisplayed(); + const vsRow = myVirtualStudies.$( + `//*[text()="${vsTitle}"]/ancestor::li[1]` + ); + vsRow.waitForDisplayed(); + + const removeBtn = vsRow.$('.fa-trash'); + removeBtn.click(); + }); + it('The VS dissapred from the landing page', function() { + goToUrlAndSetLocalStorage(CBIOPORTAL_URL, true); + $('[data-test="cancerTypeListContainer"]').waitForDisplayed(); + const vsRow = $(`//*[text()="${vsTitle}"]`); + browser.pause(100); + assert.ok(!vsRow.isExisting()); + }); +}); From c3ef88daf0f4e4d6925e6f460b91e5aabb8d77f7 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Wed, 17 Jul 2024 16:47:05 +0200 Subject: [PATCH 7/7] Add localdb e2e tests from (un)publishing of VS --- .../local/runtime-config/portal.properties | 2 + .../local/specs/virtual-study.spec.js | 132 ++++++++++++++++-- 2 files changed, 124 insertions(+), 10 deletions(-) diff --git a/end-to-end-test/local/runtime-config/portal.properties b/end-to-end-test/local/runtime-config/portal.properties index 8d38e21908e..cad2c8f36e7 100644 --- a/end-to-end-test/local/runtime-config/portal.properties +++ b/end-to-end-test/local/runtime-config/portal.properties @@ -181,6 +181,8 @@ session.service.url= # session.service.user=user # session.service.password=pass +session.endpoint.publisher-api-key=SECRETKEY + # disabled tabs, | delimited # possible values: cancer_types_summary, mutual_exclusivity, plots, mutations, co_expression, enrichments, survival, network, download, bookmark, IGV disabled_tabs= diff --git a/end-to-end-test/local/specs/virtual-study.spec.js b/end-to-end-test/local/specs/virtual-study.spec.js index 1383d3661de..d3d873180bb 100644 --- a/end-to-end-test/local/specs/virtual-study.spec.js +++ b/end-to-end-test/local/specs/virtual-study.spec.js @@ -7,6 +7,10 @@ const studyEs0Summary = CBIOPORTAL_URL + '/study/summary?id=study_es_0'; describe('Virtual Study life cycle', function() { const vsTitle = 'Test VS ' + Date.now(); + let link; + let vsId; + const X_PUBLISHER_API_KEY = 'SECRETKEY'; + it('Login and navigate to the study_es_0 study summary page', function() { goToUrlAndSetLocalStorage(studyEs0Summary, true); }); @@ -18,7 +22,7 @@ describe('Virtual Study life cycle', function() { shareVSBtn.waitForClickable(); shareVSBtn.click(); }); - it('Provid the title and save', function() { + it('Provide the title and save', function() { const modalDialog = $('.modal-dialog'); modalDialog.waitForDisplayed(); const titleInput = modalDialog.$('input#sniglet'); @@ -29,31 +33,139 @@ describe('Virtual Study life cycle', function() { saveBtn.click(); modalDialog.$('.text-success').waitForDisplayed(); const linkInput = modalDialog.$('input[type="text"]'); - const link = linkInput.getValue(); + link = linkInput.getValue(); assert.ok( link.startsWith('http'), 'The value should be link, but was ' + link ); + vsId = link + .split('?')[1] + .split('&') + .map(paramEqValue => paramEqValue.split('=')) + .find(([key, value]) => key === 'id')[1]; + assert.ok(vsId, 'Virtual Study ID has not to be empty'); }); it('See the VS in My Virtual Studies section on the landing page', function() { goToUrlAndSetLocalStorage(CBIOPORTAL_URL, true); - const myVirtualStudies = $( - '//*[text()="My Virtual Studies"]/ancestor::ul[1]' + const vsSection = $(`//*[text()="${vsTitle}"]/ancestor::ul[1]`); + vsSection.waitForDisplayed(); + const sectionTitle = vsSection.$('li label span'); + assert.equal(sectionTitle.getText(), 'My Virtual Studies'); + }); + it('Publish the VS', function() { + const result = browser.executeAsync( + function(cbioUrl, vsId, key, done) { + const url = cbioUrl + '/api/public_virtual_studies/' + vsId; + const headers = new Headers(); + headers.append('X-PUBLISHER-API-KEY', key); + fetch(url, { + method: 'POST', + headers: headers, + }) + .then(response => { + done({ + success: response.ok, + message: 'HTTP Status: ' + response.status, + }); + }) + .catch(error => { + done({ success: false, message: error.message }); + }); + }, + CBIOPORTAL_URL, + vsId, + X_PUBLISHER_API_KEY ); - myVirtualStudies.waitForDisplayed(); - const vsRow = myVirtualStudies.$( - `//*[text()="${vsTitle}"]/ancestor::li[1]` + assert.ok(result.success, result.message); + }); + it('See the VS in Public Virtual Studies section on the landing page', function() { + goToUrlAndSetLocalStorage(CBIOPORTAL_URL, true); + const vsSection = $(`//*[text()="${vsTitle}"]/ancestor::ul[1]`); + vsSection.waitForDisplayed(); + const sectionTitle = vsSection.$('li label span'); + assert.equal(sectionTitle.getText(), 'Public Virtual Studies'); + }); + it('Re-publish the VS specifying PubMed ID and type of cancer', function() { + const result = browser.executeAsync( + function(cbioUrl, vsId, key, done) { + const headers = new Headers(); + headers.append('X-PUBLISHER-API-KEY', key); + fetch( + cbioUrl + + '/api/public_virtual_studies/' + + vsId + + '?pmid=28783718&typeOfCancerId=aca', + { + method: 'POST', + headers: headers, + } + ) + .then(response => { + done({ + success: response.ok, + message: 'HTTP Status: ' + response.status, + }); + }) + .catch(error => { + done({ success: false, message: error.message }); + }); + }, + CBIOPORTAL_URL, + vsId, + X_PUBLISHER_API_KEY ); + assert.ok(result.success, result.message); + }); + it('See the VS in the Adrenocortical Adenoma section with PubMed link', function() { + goToUrlAndSetLocalStorage(CBIOPORTAL_URL, true); + const vsRow = $(`//*[text()="${vsTitle}"]/ancestor::li[1]`); + const vsSection = vsRow.parentElement(); + vsSection.waitForDisplayed(); + const sectionTitle = vsSection.$('li label span'); + assert.equal(sectionTitle.getText(), 'Adrenocortical Adenoma'); + //has PubMed link + assert.ok(vsRow.$('.fa-book').isExisting()); + }); + it('Un-publish the VS', function() { + const result = browser.executeAsync( + function(cbioUrl, vsId, key, done) { + const headers = new Headers(); + headers.append('X-PUBLISHER-API-KEY', key); + fetch(cbioUrl + '/api/public_virtual_studies/' + vsId, { + method: 'DELETE', + headers: headers, + }) + .then(response => { + done({ + success: response.ok, + message: 'HTTP Status: ' + response.status, + }); + }) + .catch(error => { + done({ success: false, message: error.message }); + }); + }, + CBIOPORTAL_URL, + vsId, + X_PUBLISHER_API_KEY + ); + assert.ok(result.success, result.message); + }); + + it('Removing the VS', function() { + goToUrlAndSetLocalStorage(CBIOPORTAL_URL, true); + const vsRow = $(`//*[text()="${vsTitle}"]/ancestor::li[1]`); vsRow.waitForDisplayed(); const removeBtn = vsRow.$('.fa-trash'); removeBtn.click(); }); - it('The VS dissapred from the landing page', function() { + + it('The VS disappears from the landing page', function() { goToUrlAndSetLocalStorage(CBIOPORTAL_URL, true); $('[data-test="cancerTypeListContainer"]').waitForDisplayed(); - const vsRow = $(`//*[text()="${vsTitle}"]`); + const vsRowTitle = $(`//*[text()="${vsTitle}"]`); browser.pause(100); - assert.ok(!vsRow.isExisting()); + assert.ok(!vsRowTitle.isExisting()); }); });