Commit 5e65fe5c authored by Piotr Gawron's avatar Piotr Gawron
Browse files

script in frontend unt tests to refresh query cache for mocking server side

This sript refreshes all GET queries. Because of that some tests had to be modified. And api resposnes are reproducible now (sets results are changed to a "sorted" set, so with every query we should have the same response).
Second big change is that overlay iamages are stored differently (there are no overlays in submaps anymore)
parent 28785dc8
......@@ -84,7 +84,7 @@ public class Target implements Serializable {
addGene(gene);
}
addReferences(references);
if (genes.size() == 1) {
if (getGenes().size() == 1) {
setType(TargetType.SINGLE_PROTEIN);
}
}
......@@ -223,7 +223,8 @@ public class Target implements Serializable {
@Override
public String toString() {
return "[" + this.getClass().getSimpleName() + "]: " + name + ", source: " + source + ", organism: " + organism + "; ";
return "[" + this.getClass().getSimpleName() + "]: " + name + ", source: " + source + ", organism: " + organism
+ "; ";
}
}
......@@ -243,19 +243,21 @@ public class ChEMBLParser extends DrugAnnotation implements IExternalService {
* @return {@link MiriamData} with {@link MiriamType#HGNC_SYMBOL} identifier
* that could be extracted from input data
* @throws DrugSearchException
* thrown when there is aproblem with annotations
* thrown when there is a problem with annotations
*/
private MiriamData targetComponentToMiriamData(Node targetComponent) throws DrugSearchException {
MiriamData result = null;
Node uniprotAccessionId = getNode("accession", targetComponent.getChildNodes());
if (uniprotAccessionId != null) {
try {
return uniprotAnnotator.uniProtToHgnc(new MiriamData(MiriamType.UNIPROT, uniprotAccessionId.getTextContent()));
result = uniprotAnnotator
.uniProtToHgnc(new MiriamData(MiriamType.UNIPROT, uniprotAccessionId.getTextContent()));
result.setAnnotator(null);
} catch (UniprotSearchException e) {
throw new DrugSearchException(e);
}
} else {
return null;
}
return result;
}
/**
......
......@@ -380,6 +380,7 @@ public class DrugbankHTMLParser extends DrugAnnotation implements IExternalServi
MiriamData uniprotTarget = new MiriamData(MiriamType.UNIPROT, uniprotId);
MiriamData hgncTarget = uniprotAnnotator.uniProtToHgnc(uniprotTarget);
if (hgncTarget != null) {
hgncTarget.setAnnotator(null);
result.addGene(hgncTarget);
} else {
result.addGene(uniprotTarget);
......
......@@ -285,13 +285,12 @@ public class ChemicalParserTest extends AnnotationTestFunctions {
@Test
public void testGetByTarget() throws Exception {
try {
// Parkinson disease
MiriamData target = new MiriamData(MiriamType.HGNC_SYMBOL, "TNF");
List<MiriamData> targets = new ArrayList<>();
targets.add(target);
List<Chemical> list = chemicalParser.getChemicalListByTarget(targets, parkinsonDiseaseId);
assertNotNull(list);
assertTrue(!list.isEmpty());
assertFalse(list.isEmpty());
} catch (Exception e) {
e.printStackTrace();
......@@ -302,7 +301,6 @@ public class ChemicalParserTest extends AnnotationTestFunctions {
@Test
public void testGetByInvalidTarget() throws Exception {
try {
// Parkinson disease
MiriamData target = new MiriamData(MiriamType.WIKIPEDIA, "TNF");
List<MiriamData> targets = new ArrayList<>();
targets.add(target);
......
......@@ -11,6 +11,7 @@
"build": "npm run clean && npm run build:css && npm run build:js",
"clean": "node scripts/clean.js",
"deploy": "node scripts/deploy.js",
"refresh-mock-requests": "node scripts/refresh_mock_requests.js",
"lint": "jshint src/.",
"test": "istanbul cover node_modules/mocha/bin/_mocha -- --recursive src/test/js"
},
......
const testFolder = './testFiles/apiCalls';
const apiBaseDir = 'http://localhost:8080/minerva/api/';
const fs = require('fs');
const path = require('path');
const request = require('request');
function listFiles(dir, filelist) {
var fs = fs || require('fs'),
files = fs.readdirSync(dir);
filelist = filelist || [];
files.forEach(function (file) {
if (fs.statSync(dir + '/' + file).isDirectory()) {
filelist = listFiles(dir + '/' + file, filelist);
}
else {
filelist.push(dir + "/" + file);
}
});
return filelist;
}
function extractUrl(file) {
var url = apiBaseDir + path.dirname(file);
url = url.replace(testFolder, "") + "/";
url = url.replace("/all/", "/*/");
//don't change "." character if it's part of a number
if (!/\.[0-9]+/.test(url)) {
url = url.replace(".", ":");
}
return url;
}
function extractLogin(file) {
var filename = file.replace(path.dirname(file), "").substr(1);
if (filename.endsWith("MOCK_TOKEN_ID&")) {
return "anonymous";
}
if (filename.endsWith("ADMIN_TOKEN_ID&")) {
return "admin";
}
return undefined;
}
function extractMethod(file) {
var filename = file.replace(path.dirname(file), "").substr(1);
var method = filename.split("=")[0];
var result;
if (method.indexOf("_") >= 0) {
result = method.split("_")[0];
} else {
result = "GET";
}
return result;
}
function setParam(params, key, value) {
if (key.indexOf(".") > 0) {
var topKey = key.split(".")[0];
if (params[topKey] === undefined) {
params[topKey] = {};
}
setParam(params[topKey], key.substr(topKey.length + 1), value)
} else {
if (value.indexOf("ALIAS.") >= 0) {
value = value.replace("ALIAS.", "ALIAS:")
}
if (value.indexOf("REACTION.") >= 0) {
value = value.replace("REACTION.", "REACTION:")
}
params[key] = value;
}
}
function extractParams(file) {
var filename = file.replace(path.dirname(file), "").substr(1);
var params = {};
var method = extractMethod(file);
if (filename.indexOf(method) === 0) {
filename = filename.substr(method.length + 1);
}
var tokens = filename.split("&");
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i];
var key = token.split("=")[0];
var value = token.split("=")[1];
if (key !== "" && key !== "token") {
setParam(params, key, value)
}
}
return params;
}
function prepareQueries(filelist) {
var result = [];
for (var i = 0; i < filelist.length; i++) {
var file = filelist[i];
result.push({
file: file,
url: extractUrl(file),
method: extractMethod(file),
login: extractLogin(file),
params: extractParams(file)
})
}
return result;
}
function getAuthToken(login) {
var url = apiBaseDir + "doLogin?login=" + login;
if (login === "anonymous") {
url += "&password=";
} else if (login === "admin") {
url += "&password=admin";
}
return new Promise(function (resolve, reject) {
var params = {
method: "GET",
url: url
};
request(params, function (error, response, body) {
if (error) {
reject(new Error(error.message));
} else if (response.statusCode !== 200) {
reject(new Error(url + " rejected with status code: " + response.statusCode));
} else {
resolve(response.headers['set-cookie']);
}
});
}).then(function (value) {
return Promise.resolve(value[0]);
});
}
function executeQuery(query) {
var url = query.url + "?";
if (query.method === "GET") {
for (var key in query.params) {
if (query.params.hasOwnProperty(key)) {
url += key + "=" + query.params[key] + "&";
}
}
}
return getAuthToken(query.login).then(function (token) {
var params = {
method: query.method,
url: url,
headers: {'Cookie': token}
};
return new Promise(function (resolve, reject) {
request(params, function (error, response, body) {
if (error) {
reject(new Error(error.message));
} else if (response.statusCode !== 200) {
reject(new Error(url + " rejected with status code: " + response.statusCode));
} else {
// for some reason sometimes result is an object not a string
if (typeof body === 'string' || body instanceof String) {
resolve(body);
} else {
resolve(JSON.stringify(body));
}
}
});
});
}).then(function (content) {
var data = fs.readFileSync(query.file, 'utf8');
if (data !== content) {
console.log("Query response changed: " + url);
console.log("Query response changed: " + url);
fs.writeFileSync(query.file, content);
if (data.length < 1000 && content.length < 1000) {
console.log("\n\n");
console.log(data);
console.log(content);
console.log("\n\n");
}
}
});
}
function executeQueries(queries) {
var promises = [];
// for (var i = 0; i < 3; i++) {
for (var i = 0; i < queries.length; i++) {
var query = queries[i];
if (query.method !== "GET" || query.url.indexOf(":downloadModel") >= 0) {
console.log("Ignoring " + query.method + " query: " + query.url);
} else {
// console.log("Exec " + query.method + " query: " + query.url);
// console.log(query.params);
promises.push(executeQuery(query));
}
}
return Promise.all(promises);
}
var files = listFiles(testFolder);
var queries = prepareQueries(files);
return executeQueries(queries).catch(function (error) {
console.log(error);
process.exit(1);
});
......@@ -47,19 +47,19 @@ Export.prototype._createGui = function() {
new Header({
element : headerDiv,
customMap : null,
project : self.getProject(),
project : self.getProject()
});
self.getElement().appendChild(headerDiv);
var panels = [ {
name : "ELEMENTS",
panelClass : ElementExportPanel,
panelClass : ElementExportPanel
}, {
name : "NETWORK",
panelClass : NetworkExportPanel,
panelClass : NetworkExportPanel
}, {
name : "GRAPHICS",
panelClass : GraphicsExportPanel,
panelClass : GraphicsExportPanel
} ];
var tabDiv = Functions.createElement({
......
......@@ -760,7 +760,12 @@ ServerConnector.getProject = function (projectId) {
projectId = result;
queryParams.projectId = result;
return self.sendGetRequest(self.getProjectUrl(queryParams, filterParams));
}).catch(function (error) {
return self.processNetworkError(error);
}).then(function (content) {
if (content === null) {
return null;
} else {
var downloadedProject = new Project(content);
if (self._projectsById[projectId] !== undefined) {
self._projectsById[projectId].update(downloadedProject);
......@@ -768,9 +773,20 @@ ServerConnector.getProject = function (projectId) {
self._projectsById[projectId] = downloadedProject;
}
project = self._projectsById[projectId];
return self.getModels(projectId);
}).then(function (models) {
return self.getModels(projectId).then(function (models) {
project.setModel(models[0]);
return self.getOverlays({
projectId: projectId,
publicOverlay: true
});
}).then(function (overlays) {
if (project.getModel() !== undefined) {
project.getModel().addLayouts(overlays);
} else {
if (overlays.length > 0) {
logger.warn("Cannot add overlays to the project: " + project.getProjectId());
}
}
return self.getLoggedUser();
}).then(function (user) {
return self.getOverlays({
......@@ -787,18 +803,7 @@ ServerConnector.getProject = function (projectId) {
}
}
return project;
}).then(null, function (error) {
if ((error instanceof NetworkError)) {
switch (error.statusCode) {
case HttpStatus.NOT_FOUND:
return null;
case HttpStatus.FORBIDDEN:
return Promise.reject(new SecurityError("Access denied."));
default:
return Promise.reject(error);
}
} else {
return Promise.reject(error);
});
}
});
};
......
......@@ -374,6 +374,7 @@ OverlayPanel.prototype.refresh = function (showDefault) {
var title = self.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TITLE);
var addButton = self.getControlElement(PanelControlElementType.OVERLAY_ADD_OVERLAY_BUTTON);
var tableElement = self.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE);
if (user.getLogin() === "anonymous") {
title.innerHTML = 'YOU ARE NOT LOGGED IN. PLEASE, <a href="#">LOG IN</a>'
+ 'TO UPLOAD AND VIEW CUSTOM OVERLAYS<br/><center><button>LOGIN</button></center>';
......@@ -383,10 +384,11 @@ OverlayPanel.prototype.refresh = function (showDefault) {
$(title).find("a")[0].onclick = openLoginDialog;
$(title).find("button")[0].onclick = openLoginDialog;
addButton.style.display = "none";
$(tableElement).hide();
} else {
$(tableElement).show();
title.innerHTML = self.getCustomOverlaysMessage();
addButton.style.display = "block";
var tableElement = self.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE);
table = $(tableElement).on('order.dt', function (e) {
if ($(tableElement).dataTable().fnSettings().aaSorting[0][0] === 0) {
......
......@@ -90,13 +90,14 @@ AbstractCustomMap.prototype.getMarkerSurfaceCollection = function () {
*
*/
AbstractCustomMap.prototype.setupLayouts = function () {
for (var i = 0; i < this.getLayouts().length; i++) {
var layout = this.getLayouts()[i];
var typeOptions = this.createTypeOptions(layout);
var overlays = this.getTopMap().getLayouts();
for (var i = 0; i < overlays.length; i++) {
var overlay = overlays[i];
var typeOptions = this.createTypeOptions(overlay);
var mapType = new google.maps.ImageMapType(typeOptions);
this.getGoogleMap().mapTypes.set(layout.getId().toString(), mapType);
this.getGoogleMap().mapTypes.set(overlay.getId().toString(), mapType);
}
this.getGoogleMap().setMapTypeId(this.getLayouts()[0].getId().toString());
this.getGoogleMap().setMapTypeId(overlays[0].getId().toString());
};
/**
......@@ -179,7 +180,7 @@ AbstractCustomMap.prototype.createTypeOptions = function (param) {
if (coord.y < 0 || coord.y >= maxTileYRange || coord.x < 0 || coord.x >= maxTileXRange) {
return null;
}
return "../map_images/" + param.getDirectory() + "/" + zoom + "/" + coord.x + "/" + coord.y + ".PNG";
return "../map_images/" + self.getProject().getDirectory() + "/" + param.getImagesDirectory(self.getId()) + "/" + zoom + "/" + coord.x + "/" + coord.y + ".PNG";
},
tileSize: new google.maps.Size(self.getTileSize(), self.getTileSize()),
maxZoom: self.getMaxZoom(),
......
......@@ -239,7 +239,7 @@ CustomMap.prototype.openDataOverlay = function (param) {
var submaps = self.getSubmaps();
for (var i = 0; i < submaps.length; i++) {
var submap = submaps[i];
submap.openDataOverlay(submap.getModel().getLayouts()[index].getId());
submap.openDataOverlay(identifier);
}
return Promise.resolve();
}
......
......@@ -18,7 +18,7 @@ function LayoutData(layoutId, name) {
var object = layoutId;
this.setId(object.idObject);
this.setName(object.name);
this.setDirectory(object.directory);
this.setImagesDirectory(object.images);
this.setDescription(object.description);
this.setCreator(object.creator);
this.setContent(object.content);
......@@ -112,12 +112,17 @@ LayoutData.prototype.setName = function (name) {
this.name = name;
};
LayoutData.prototype.getDirectory = function () {
return this._directory;
LayoutData.prototype.getImagesDirectory = function (modelId) {
for (var i = 0; i < this._imagesDirectory.length; i++) {
if (parseInt(this._imagesDirectory[i].modelId) === modelId) {
return this._imagesDirectory[i].path;
}
}
return null;
};
LayoutData.prototype.setDirectory = function (directory) {
this._directory = directory;
LayoutData.prototype.setImagesDirectory = function (imagesDirectory) {
this._imagesDirectory = imagesDirectory;
};
LayoutData.prototype.updateAlias = function (layoutAlias) {
......
......@@ -75,7 +75,6 @@ function MapModel(configuration) {
this.setHeight(configuration.height);
this.setMinZoom(configuration.minZoom);
this.setMaxZoom(configuration.maxZoom);
this.addLayouts(configuration.layouts);
this.addSubmodels(configuration.submodels);
this.setCenterLatLng(configuration.centerLatLng);
this.setTopLeftLatLng(configuration.topLeftLatLng);
......@@ -631,7 +630,7 @@ MapModel.prototype.addLayout = function (layout) {
if (object === undefined) {
this._layoutsData[layoutData.getId()] = layoutData;
} else {
logger.warn("Layout " + layoutData.getId() + " already exists in a model: " + this.getId());
throw new Error("Layout " + layoutData.getId() + " already exists in a model: " + this.getId());
}
};
......
......@@ -7,6 +7,7 @@ var ObjectWithListeners = require('../../ObjectWithListeners');
var Annotation = require("./Annotation");
var Model = require('./MapModel');
// noinspection JSUnusedLocalSymbols
var logger = require('../../logger');
function Project(data) {
......@@ -36,6 +37,7 @@ Project.prototype.loadFromData = function (data) {
} else {
self.setId(parseInt(data.idObject));
self.setProjectId(data.projectId);
self.setDirectory(data.directory);
self.setVersion(data.version);
self.setName(data.name);
self.setOverviewImages(data.overviewImageViews);
......@@ -56,6 +58,7 @@ Project.prototype.update = function (data) {
var self = this;
self.setId(data.getId());
self.setProjectId(data.getProjectId());
self.setDirectory(data.getDirectory());
self.setVersion(data.getVersion());
self.setName(data.getName());
self.setOverviewImages(data.getOverviewImages());
......@@ -107,6 +110,14 @@ Project.prototype.setProjectId = function (projectId) {
this._projectId = projectId;
};
Project.prototype.getDirectory = function () {
return this._directory;
};
Project.prototype.setDirectory = function (directory) {
this._directory = directory;
};
Project.prototype.getVersion = function () {
return this._version;
};
......
......@@ -20,6 +20,7 @@ describe('Admin', function () {
describe('logout', function () {
it('default', function () {
var admin = new Admin(helper.createCustomMapOptions());
helper.loginAsAdmin();
var token = ServerConnector.getSessionData().getToken();
return admin.init().then(function () {
assert.ok(token === ServerConnector.getSessionData().getToken());
......
......@@ -99,25 +99,27 @@ describe('ServerConnector', function () {
});
});
it('getReactions with empty list of ids', function () {
return ServerConnector.getReactions([]).then(function (result) {
assert.equal(result.length, 2);
describe('getReactions', function () {
it('with empty list of ids', function () {
return ServerConnector.getReactions({ids: []}).then(function (result) {
assert.equal(result.length, 28);
var reaction = result[0];
assert.ok(reaction instanceof Reaction);
assert.equal(reaction.getId(), 153513);
assert.equal(reaction.getId(), 153524);
assert.equal(reaction.getModelId(), 15781);
});
});
it('getReactions without ids', function () {
it('without ids', function () {
return ServerConnector.getReactions([]).then(function (result) {
assert.equal(result.length, 2);
assert.equal(result.length, 28);
var reaction = result[0];
assert.ok(reaction instanceof Reaction);
assert.equal(reaction.getId(), 153513);
assert.equal(reaction.getId(), 153524);
assert.equal(reaction.getModelId(), 15781);
});
});
});
it('getElements with empty list of ids', function () {
return ServerConnector.getAliases({}).then(function (result) {
......@@ -133,7 +135,7 @@ describe('ServerConnector', function () {
assert.equal(result.length, 1);