Commit 9804b28b authored by Maxime Chaillet's avatar Maxime Chaillet Committed by Chaillet Maxime

use karma to test the app. display the proposal and beamline in a table.

parent 459a58d1
RewriteEngine On
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
......
......@@ -7,26 +7,29 @@
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- Using grunt-wiredep, the proper js files from bower components are included below -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/dustjs-linkedin/dist/dust-full.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/dustjs-helpers/dist/dust-helpers.min.js"></script>
<script src="bower_components/lodash/lodash.js"></script>
<script src="bower_components/moment/moment.js"></script>
<!-- endbower -->
<!-- Using grunt-include-source, the proper js files created by us (not minified) are included below -->
<script src="src/author.js"></script>
<script src="src/beamlineurl.js"></script>
<script src="src/citation.js"></script>
<script src="src/constants.js"></script>
<script src="src/doicontroller.js"></script>
<script src="src/doiData.js"></script>
<script src="src/doiview.js"></script>
<script src="src/event.js"></script>
<script src="src/experimentalreportcontroller.js"></script>
<script src="src/jsonextractor.js"></script>
<script src="src/metadataTableHelper.js"></script>
<!-- Using grunt-wiredep, the proper js files from bower components are included below -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/dustjs-linkedin/dist/dust-full.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/dustjs-helpers/dist/dust-helpers.min.js"></script>
<script src="bower_components/lodash/lodash.js"></script>
<script src="bower_components/moment/moment.js"></script>
<!-- endbower -->
<!-- bower:css -->
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
......
......@@ -7,13 +7,14 @@
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- Using grunt-include-source, the proper js files created by us (not minified) are included below -->
<!-- include: "type": "js", "files": "src/*.js" -->
<!-- Using grunt-wiredep, the proper js files from bower components are included below -->
<!-- bower:js -->
<!-- endbower -->
<!-- Using grunt-include-source, the proper js files created by us (not minified) are included below -->
<!-- include: "type": "js", "files": "src/*.js" -->
<!-- bower:css -->
<!-- endbower -->
......
// Karma configuration
// Generated on Thu Oct 11 2018 23:09:22 GMT+0200 (CEST)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'browserify'],
// list of files / patterns to load in the browser
files: [
'src/jsonextractor.js',
'src/constants.js',
'tests/jsonExtractor.test.js',
'bower_components/lodash/lodash.js'
],
// list of files / patterns to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'tests/jsonExtractor.test.js': [ 'browserify' ]
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Firefox'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
{
"name": "doi-landing-page",
"jest": {
"rootDir": "tests"
},
"version": "0.0.0",
"description": "",
"main": "Gruntfile.js",
......@@ -16,15 +13,22 @@
"grunt-wiredep": "^3.0.1"
},
"devDependencies": {
"browserify": "^16.2.3",
"grunt": "^1.0.1",
"grunt-contrib-cssmin": "^2.2.1",
"grunt-contrib-jshint": "^1.1.0",
"grunt-include-source": "^1.1.0",
"grunt-plato": "^1.4.0",
"jest": "^23.6.0"
"jasmine-core": "^3.2.1",
"karma": "^3.0.0",
"karma-browserify": "^5.3.0",
"karma-chrome-launcher": "^2.2.0",
"karma-firefox-launcher": "^1.1.0",
"karma-jasmine": "^1.1.2",
"watchify": "^3.11.0"
},
"scripts": {
"test": "jest --watchAll"
"test": "./node_modules/jest/bin/jest.js"
},
"repository": {
"type": "git",
......
var CONSTANTS = {
ES_RESOURCE_TYPE : "experimental session resource type",
DC_RESOURCE_TYPE : "dataset collection resource type"
};
//module.exports = CONSTANTS;
......@@ -3,6 +3,7 @@ function DoiData() {
}
/**
* Get the accessibility status
* @param {string} resourceType the resource type for this DOI
* @param {string} sessionDate The timeStamp the experiment was started
* @param {string} publiclyAccessibleYear The year the data will be publicly accesssible.
* @return {string}
......@@ -10,19 +11,24 @@ function DoiData() {
* "Restricted access" : the data is still under embargo. Only accessible to experimental team members
*
* */
DoiData.prototype.getAccessibilityStatus = function( sessionDate, publiclyAccessibleYear ) {
if ( publiclyAccessibleYear && sessionDate ) {
var publiclyAvailableDate = moment( publiclyAccessibleYear, "YYYY" );
DoiData.prototype.getAccessibilityStatus = function (resourceType, sessionDate, publiclyAccessibleYear) {
if (resourceType) {
if (resourceType === CONSTANTS.ES_RESOURCE_TYPE) {
if (publiclyAccessibleYear && sessionDate) {
var publiclyAvailableDate = moment(publiclyAccessibleYear, "YYYY");
var now = moment();
if ( now > publiclyAvailableDate ) {
if (now > publiclyAvailableDate) {
return "Open access";
} else if ( now <= publiclyAvailableDate ) {
} else if (now <= publiclyAvailableDate) {
return "Restricted access";
}
}
console.log( "Failed to determine whether the accessibility of the DOI." );
} else if (resourceType === CONSTANTS.DC_RESOURCE_TYPE){
return "Open access";
}
}
console.log("Failed to determine whether the accessibility of the DOI.");
return "Accessibility status could not be determined";
};
......@@ -2,21 +2,21 @@ function DOIController(view) {
var _this = this;
// doiServer = the server which provides doi details from a given doi name.
//this.doiServer = "https://data.datacite.org/";
this.doiServer = "https://api.test.datacite.org/"
this.doiServer = "https://api.test.datacite.org/";
// 10.5072 is the test esrf doi prefix;
// 10.15151 is the production esrf doi prefix;
this.acceptedPrefix = [ "10.5072", "10.15151" ];
this.acceptedPrefix = ["10.5072", "10.15151"];
this.view = view;
this.experimentalReportController = new ExperimentalReportController();
this.experimentalReportController.onSuccess.attach(function(sender, data) {
this.experimentalReportController.onSuccess.attach(function (sender, data) {
_this.view.renderExperimentalReportData(data);
});
this.experimentalReportController.onError.attach(function(sender, data) {
this.experimentalReportController.onError.attach(function (sender, data) {
console.log("Error when retrieving fileList from SMIS.");
_this.view.renderErrorForExperimentalReport();
});
......@@ -28,38 +28,38 @@ function DOIController(view) {
* fields when the doi does not exist. In this case the following code is
* executed. Reloading the page is treated by .fail as it should be.
*/
DOIController.prototype.isValidDOIData = function(doiData) {
DOIController.prototype.isValidDOIData = function (doiData) {
if (_.keysIn(doiData).length > 3) {
return _.find(_.keysIn(doiData), function(value) {
return _.find(_.keysIn(doiData), function (value) {
return value === "title";
}).length > 0;
}
return false;
};
DOIController.prototype.getData = function(doi) {
DOIController.prototype.getData = function (doi) {
var _this = this;
this.view.setDOIInTopBanner(doi);
if (this.hasAcceptedPrefix(doi)) {
$.ajax({
headers : {
Accept : "application/vnd.datacite.datacite+json"
headers: {
Accept: "application/vnd.datacite.datacite+json"
},
type : "GET",
timeout : 15000, // triggers timeout when request pends longer than
type: "GET",
timeout: 15000, // triggers timeout when request pends longer than
// 5000ms
url : this.doiServer + doi,
beforeSend : function(xhr) {
url: this.doiServer + doi,
beforeSend: function (xhr) {
_this.view.setLoading("Retrieving data from Server");
xhr.setRequestHeader ("Authorization", "Basic " + btoa("DATACITE.ESRF" + ":" + "datacyte1")); // to be removed as well as the parameter
xhr.setRequestHeader("Authorization", "Basic " + btoa("DATACITE.ESRF" + ":" + "datacyte1")); // to be removed as well as the parameter
},
complete : function() {
complete: function () {
_this.view.setLoading(false);
}
})
.done(function(data) {
.done(function (data) {
if (data) {
// Test abnormal length of the json object
if (!_this.isValidDOIData(data)) {
......@@ -78,19 +78,22 @@ DOIController.prototype.getData = function(doi) {
doiData.publiclyAccessibleYear = data.publication_year;
doiData.proposalType = jsonExtractor.getFieldFromSubject(data.subject, "Proposal Type Description");
doiData.proposalNumber = jsonExtractor.getFieldFromSubject(data.subject, "Proposal");
doiData.proposalName = jsonExtractor.getFieldFromSubject(data.subject, "Proposal");
_this.experimentalReportController.requestFilenameList(doiData.proposalNumber);
_this.experimentalReportController.requestFilenameList(doiData.proposalName);
doiData.beamline = jsonExtractor.getFieldFromSubject(data.subject, "instrument");
doiData.beamline = jsonExtractor.getFieldFromSubject(data.subject, "Instrument");
doiData.investigationId = jsonExtractor.extractInvestigationId(data);
doiData.accessibility = doiData.getAccessibilityStatus(doiData.sessionDate, doiData.publiclyAccessibleYear);
doiData.resourceType = jsonExtractor.getResourceType(data);
doiData.accessibility = doiData.getAccessibilityStatus(doiData.resourceType, doiData.sessionDate, doiData.publiclyAccessibleYear);
doiData.accessMessage = _this.view.setDataAccessMessage(doiData);
doiData.citation = _this.createCitation(data);
doiData.resourceTypeGeneral = jsonExtractor.getResourceTypeGeneral(data);
doiData.resourceType = jsonExtractor.getResourceType(data);
// constants passed for tests in the templates
doiData.DC_RESOURCE_TYPE = CONSTANTS.DC_RESOURCE_TYPE;
doiData.ES_RESOURCE_TYPE = CONSTANTS.ES_RESOURCE_TYPE;
// Set the URL corresponding to the beamline name.
if (data.date_collected) {
......@@ -105,7 +108,7 @@ DOIController.prototype.getData = function(doi) {
_this.view.renderDOIData(doiData);
}
}
}).fail(function(jqXHR, textStatus, errorThrown) {
}).fail(function (jqXHR, textStatus, errorThrown) {
_this.view.renderError(jqXHR, errorThrown, _this.origin);
_this.view.setLoading(false);
});
......@@ -122,19 +125,19 @@ DOIController.prototype.getData = function(doi) {
* @return true if the prefix is an esrf prefix, false otherwise
*
*/
DOIController.prototype.hasAcceptedPrefix = function(doi) {
DOIController.prototype.hasAcceptedPrefix = function (doi) {
var prefix = doi.split('/')[0];
return (_.findIndex(this.acceptedPrefix, function(o) {
return (_.findIndex(this.acceptedPrefix, function (o) {
return prefix == o;
}) != -1);
};
// Selects what will be displayed in the main id div
DOIController.prototype.displayMainContent = function(doi) {
DOIController.prototype.displayMainContent = function (doi) {
var isDOIProvided = false;
if (this.origin === "welcome-page") {
dust.render('welcome_tpl', {}, function(err, out) {
dust.render('welcome_tpl', {}, function (err, out) {
$("#main").html(out);
});
}
......@@ -151,7 +154,7 @@ DOIController.prototype.displayMainContent = function(doi) {
* @param {string}
* origin The origin page this call is made from
*/
DOIController.prototype.setOrigin = function(origin) {
DOIController.prototype.setOrigin = function (origin) {
this.origin = origin;
};
......@@ -164,7 +167,7 @@ DOIController.prototype.setOrigin = function(origin) {
* date The date the experiment was performed.
* @return the url of the beamLine, null if it is not found
*/
DOIController.prototype.getBeamlineUrl = function(beamline, date) {
DOIController.prototype.getBeamlineUrl = function (beamline, date) {
for (var i = 0; i < BEAMLINEURL.length; i++) {
var startDate = moment(BEAMLINEURL[i].startDate);
var endDate = moment(BEAMLINEURL[i].endDate);
......@@ -185,7 +188,7 @@ DOIController.prototype.getBeamlineUrl = function(beamline, date) {
* @return {string}
* citation : the citation to be displayed
*/
DOIController.prototype.createCitation = function(data) {
DOIController.prototype.createCitation = function (data) {
// Authors sent in json can be in several format. The following call find
// first name and last name when possible.
var citation = new Citation(data);
......
......@@ -3,6 +3,7 @@ function DOIView() {
this.mainPanelId = "main";
this.reportPanelId = "expReport";
this.badgePanelId = "badges";
this.metadataDivId = 'metadata';
this.reportExperimentFileNames = null;
this.failedRecievingExpReport = false;
......@@ -58,6 +59,7 @@ DOIView.prototype.renderDOIData = function (doiData) {
$('#' + _this.mainPanelId).html(out);
_this.isDOIAlreadyRendered = true;
_this.renderBadges(doiData);
_this.renderMetadata(doiData);
/**
* If there are experimental reports already retrieved then render them after
* the rendering of the DOI
......@@ -131,9 +133,8 @@ DOIView.prototype.renderErrorForExperimentalReport = function () {
/**
* Render the badge template in the corresponding div
*
* */
* @param {object} data : the doiData object as constructed by the doiController
*/
DOIView.prototype.renderBadges = function (data) {
if (data) {
var _this = this;
......@@ -143,10 +144,24 @@ DOIView.prototype.renderBadges = function (data) {
}, function (err, out) {
$('#' + _this.badgePanelId).html(out);
});
}
};
/**
* Render the badge template in the corresponding div
*/
DOIView.prototype.renderMetadata = function (data) {
if (data) {
var _this = this;
dust.render('metadata_tpl', {
data: data
}, function (err, out) {
$('#' + _this.metadataDivId).html(out);
});
}
};
/**
* Set the message which is displayed just above the "Access data button" in experimental data box.
*
......
function JsonExtractor(json) {
}
......@@ -14,7 +13,7 @@ function JsonExtractor(json) {
JsonExtractor.prototype.extractInvestigationId = function (data) {
var regExp = RegExp(/\/\w*-*[Ee][Ss][Rr][Ff]-[Ee][Ss]-(\d+)$/);
//return regExp.exec( data.doi )[1];
return "investigationId"
return "investigationId";
};
/**
......@@ -28,13 +27,16 @@ JsonExtractor.prototype.extractInvestigationId = function (data) {
JsonExtractor.prototype.getFieldFromSubject = function (subject, field) {
if (subject) {
if (subject[0]) {
var regExp = new RegExp("^" + field, 'i');
for (var i = 0; i < subject[0].length; i++) {
if (subject[0][i].subject_scheme === field) {
if (regExp.test(subject[0][i].subject_scheme)) {
if (subject[0][i].text) {
return _.split(subject[0][i].text, ',');
}
}
}
}
}
return null;
};
......@@ -89,14 +91,17 @@ JsonExtractor.prototype.getResourceTypeGeneral = function (data) {
/**
* Get the resource type
* @param {object}
* data The data object provided by datacite
* @return {string}
* The resource tyoe. Null if it does not exist.
* @param {object} data The data object provided by datacite
* @return {string} Resource tyoe. Null if it does not exist.
* */
JsonExtractor.prototype.getResourceType = function (data) {
if (data && data.resource_type) {
return data.resource_type;
if (data.resource_type === "Experiment Session") {
return CONSTANTS.ES_RESOURCE_TYPE;
}
if (data.resource_type === "Datacollection") {
return CONSTANTS.DC_RESOURCE_TYPE;
}
}
return null;
};
\ No newline at end of file
function proposalBeamLineTable(chunk, context, bodies, params) {
var proposals = params.proposals;
var beamlines = params.beamlines;
chunk.write('<table class="table table-striped">');
chunk.write('<thead>');
chunk.write('<tr>');
chunk.write('<th scope="col">Proposal</th>');
chunk.write('<th scope="col">Beamline</th>');
chunk.write('</tr>');
chunk.write('</thead>');
chunk.write('<tbody>');
for (let index = 0; index < proposals.length; index++) {
const proposal = proposals[index];
const beamline = beamlines[index];
chunk.write('<tr>');
chunk.write('<td>' + proposals[index] + '</td>');
if (beamlines[index]) {
chunk.write('<td>' + beamlines[index] + '</td>');
} else {
chunck.write('<td> unknown </td>');
}
chunk.write('</tr>');
}
chunk.write('</tbody>');
chunk.write('</table>');
return chunk.render(bodies.block, context);
}
dust.helpers.proposalBeamLineTable = proposalBeamLineTable;
<div class="row margin-left-0 margin-right-0">
{@eq key=data.resourceType value="Experiment Session"}
{@eq key=data.resourceType value=CONSTANTS.ES_RESOURCE_TYPE}
<div class="col-auto padding-right-2 padding-left-2">
<span class="badge badge-secondary font-1p4rem " > Session </span>
</div>
{/eq}
{@eq key=data.resourceType value=CONSTANTS.DC_RESOURCE_TYPE}
<div class="col-auto padding-right-2 padding-left-2">
<span class="badge badge-secondary font-1p4rem " > Collection </span>
</div>
{/eq}
<div class="col"> </div>
{@eq key=data.resourceTypeGeneral value="Dataset"}
......
......@@ -54,67 +54,7 @@
<hr>
<div class="row">
<div class="col">
<div class="myBorder-left">
<label> Proposal </label>
{?data.proposalNumber}
<div class="padding-left-15">{data.proposalNumber}</div>
{:else}
<div class="padding-left-15"> Not available</div>
{/data.proposalNumber}
</div>
</div>
<div class="col">
<div class="myBorder-left">
<label> Publication year </label>
{?data.mintingYear}
<div class="padding-left-15">{data.mintingYear}</div>
{:else}
<div class="padding-left-15"> Not available</div>
{/data.mintingYear}
</div>
</div>
<div class="col">
<div class="myBorder-left">
<label> Beamline </label>
{?data.beamline}
{@eq key=data.beamlineUrl value="noLink"}
<div class="padding-left-15">{data.beamline}</div>
{:else}
<div class="padding-left-15">
<a href="{data.beamlineUrl}" target="_blank"> {data.beamline} </a>
</div>
{/eq}
{:else}
<div class="padding-left-15">Not available</div>
{/data.beamline}
</div>
</div>
<div class="col">
<div class="myBorder-left">
<label> Session date </label>
{?data.sessionDate}
<div class="padding-left-15">{data.sessionDate}</div>
{:else}
<div class="padding-left-15"> Not available</div>
{/data.sessionDate}
</div>
</div>
<div class="col-4">
<div class="myBorder-left">
<label>Category </label>
{?data.proposalType}
<div class="padding-left-15">{data.proposalType}</div>
{:else}
<div class="padding-left-15"> Not available</div>
{/data.proposalType}
</div>
</div>
<div class="row" id="metadata">
</div>
<hr>
......@@ -157,7 +97,7 @@
<div class="row">
<div class="col-1"> </div>
<div class="col-10">
<form action="https://icat.esrf.fr/#/browse/facility/ESRF/proposal/{data.proposalNumber}/investigation/{data.investigationId}/dataset" target="_blank">
<form action="https://icat.esrf.fr/#/browse/facility/ESRF/proposal/{data.proposalName}/investigation/{data.investigationId}/dataset" target="_blank">
<button type="submit" class="btn btn-primary btn-lg btn-block"> Access data </button>
</form>
</div>
......