Skip to content

Commit

Permalink
Merge pull request #274 from bcgsc/feat/DEVSU-2049-kbmatches-to-poten…
Browse files Browse the repository at this point in the history
…tial

[DEVSU-2049] kbmatches to potential
  • Loading branch information
kttkjl authored Nov 10, 2023
2 parents 0b89d6e + 5b56a51 commit 4314f7e
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 11 deletions.
41 changes: 41 additions & 0 deletions app/api/graphkb.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,48 @@ const graphkbEvidenceLevels = async (graphkbToken) => {
});
};

/* Get Statement info from GraphKB
*
* @param {string} graphkbToken the Authorization token for the connection to GraphKB
* @param {string} statementId the statement RID to query GraphKB with
*
* @returns {object} response body from graphkb
*/
const graphkbStatement = async (graphkbToken, statementId) => {
const {uri} = CONFIG.get('graphkb');

const query = {
filters: [
{'@rid': `${statementId}`},
],
limit: 1,
target: 'Statement',
returnProperties: [
'conditions.@rid',
'conditions.@class',
'conditions.displayName',
'conditions.reference1.displayName',
'conditions.type.displayName',
'conditions.reference2.displayName',
'relevance.@rid',
'relevance.displayName',
],
};

return request({
url: `${uri}/query`,
method: 'POST',
body: JSON.stringify(query),
json: true,
headers: {
Authorization: graphkbToken,
'Content-Type': 'application/json',
},
});
};

module.exports = {
graphkbAutocomplete,
graphkbEvidenceLevels,
graphkbStatement,
};
33 changes: 26 additions & 7 deletions app/routes/graphkb/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const HTTP_STATUS = require('http-status-codes');
const {StatusCodes} = require('http-status-codes');
const express = require('express');

const logger = require('../../log');
const loginMiddleware = require('../../middleware/graphkb');
const {graphkbAutocomplete, graphkbEvidenceLevels} = require('../../api/graphkb');
const {graphkbAutocomplete, graphkbEvidenceLevels, graphkbStatement} = require('../../api/graphkb');

const router = express.Router({mergeParams: true});

Expand All @@ -15,11 +15,15 @@ router.use(loginMiddleware);
*/
router.get('/:targetType(variant|therapy|evidenceLevel|context)', async (req, res) => {
try {
const data = await graphkbAutocomplete(req.params.targetType, req.graphkbToken, req.query?.search);
return res.status(HTTP_STATUS.OK).json(data);
const data = await graphkbAutocomplete(
req.params.targetType,
req.graphkbToken,
req.query?.search,
);
return res.status(StatusCodes.OK).json(data);
} catch (error) {
logger.error(error);
return res.status(HTTP_STATUS.SERVICE_UNAVAILABLE).json(`GraphKB lookup error: ${error}`);
return res.status(StatusCodes.SERVICE_UNAVAILABLE).json(`GraphKB lookup error: ${error}`);
}
});

Expand All @@ -31,10 +35,25 @@ router.get('/evidence-levels', async (req, res) => {
const {graphkbToken} = req;
try {
const data = await graphkbEvidenceLevels(graphkbToken);
return res.status(HTTP_STATUS.OK).json(data);
return res.status(StatusCodes.OK).json(data);
} catch (error) {
logger.error(error);
return res.status(HTTP_STATUS.SERVICE_UNAVAILABLE).json(`GraphKB lookup error: ${error}`);
return res.status(StatusCodes.SERVICE_UNAVAILABLE).json(`GraphKB lookup error: ${error}`);
}
});

/**
* Endpoint for retrieving Statement related info from GraphKB. This endpoint is used by the client
* for getting @rids from graphKB to be used to add kbmatches to potential therapeutic targets
*/
router.get('/statements/:statementId', async (req, res) => {
const {graphkbToken} = req;
try {
const data = await graphkbStatement(graphkbToken, req.params.statementId);
return res.status(StatusCodes.OK).json(data);
} catch (error) {
logger.error(error);
return res.status(StatusCodes.SERVICE_UNAVAILABLE).json(`GraphKB lookup error: ${error}`);
}
});

Expand Down
53 changes: 53 additions & 0 deletions test/graphkb.mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,58 @@ jest.mock('../app/api/graphkb', () => {
}],
};
},

graphkbStatement: async (graphkbToken, statementId) => {
if (!graphkbToken) {
throw new Error('Invalid token');
}
if (!statementId) {
throw new Error('No statementId given');
}

return {
metadata: {
records: 1,
},
result: [
{
conditions: [
{
'@class': 'PositionalVariant',
'@rid': '#159:5455',
displayName: 'BRAF:p.V600E',
reference1: {
displayName: 'BRAF',
},
reference2: null,
type: {
displayName: 'missense mutation',
},
},
{
'@class': 'Therapy',
'@rid': '#123:40604',
displayName: 'panitumumab [DB01269]',
reference1: null,
reference2: null,
type: null,
},
{
'@class': 'Disease',
'@rid': '#135:19439',
displayName: 'colorectal adenocarcinoma [COADREAD]',
reference1: null,
reference2: null,
type: null,
},
],
relevance: {
'@rid': '#146:46',
displayName: 'resistance',
},
},
],
};
},
};
});
44 changes: 40 additions & 4 deletions test/routes/graphkb.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const HTTP_STATUS = require('http-status-codes');
const {StatusCodes} = require('http-status-codes');
const supertest = require('supertest');
const getPort = require('get-port');
// get test user info
Expand All @@ -16,7 +16,7 @@ const testAutocompleteWithKeyword = async (request, type, keyword) => {
.get(`${BASE_URL}/${type}?search=${keyword}`)
.auth(username, password)
.type('json')
.expect(HTTP_STATUS.OK);
.expect(StatusCodes.OK);

expect(body).toEqual(
expect.objectContaining({
Expand All @@ -38,7 +38,7 @@ const testAutocompleteWithoutKeyword = async (request, type) => {
.get(`${BASE_URL}/${type}`)
.auth(username, password)
.type('json')
.expect(HTTP_STATUS.OK);
.expect(StatusCodes.OK);

expect(body).toEqual(
expect.objectContaining({
Expand Down Expand Up @@ -129,9 +129,45 @@ describe('GET /graphkb/evidence-levels', () => {
.get(`${BASE_URL}/evidence-levels`)
.auth(username, password)
.type('json')
.expect(HTTP_STATUS.OK);
.expect(StatusCodes.OK);

expect(body.result.length).toBeGreaterThan(0);
expect(body.result[0]).toHaveProperty('description');
});
});

describe('GET /graphkb/statements/:statementId', () => {
let server;
let request;

beforeAll(async () => {
const port = await getPort({port: CONFIG.get('web:port')});
server = await listen(port);
request = supertest(server);
});

afterAll(async () => {
await server.close();
});

test('returns one statement with the correct params', async () => {
const {body} = await request
.get(`${BASE_URL}/statements/156:13495`)
.auth(username, password)
.type('json')
.expect(StatusCodes.OK);

expect(body.result.length).toEqual(1);
expect(body.metadata.records).toEqual(1);
expect(body.result[0]).toHaveProperty('conditions');
expect(body.result[0].conditions[0]).toHaveProperty('@rid');
expect(body.result[0].conditions[0]).toHaveProperty('@class');
expect(body.result[0].conditions[0]).toHaveProperty('displayName');
expect(body.result[0].conditions[0]).toHaveProperty('reference1');
expect(body.result[0].conditions[0]).toHaveProperty('reference2');
expect(body.result[0].conditions[0]).toHaveProperty('type');
expect(body.result[0]).toHaveProperty('relevance');
expect(body.result[0].relevance).toHaveProperty('@rid');
expect(body.result[0].relevance).toHaveProperty('displayName');
});
});

0 comments on commit 4314f7e

Please sign in to comment.