Skip to content

Commit

Permalink
Merge branch 'release-4.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
oat-github-bot committed Dec 1, 2023
2 parents 55aea36 + c208e67 commit 370a178
Show file tree
Hide file tree
Showing 10 changed files with 633 additions and 3 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@oat-sa/tao-test-runner-qti",
"version": "4.0.0",
"version": "4.1.0",
"description": "TAO Test Runner QTI implementation",
"files": [
"dist",
Expand Down
76 changes: 76 additions & 0 deletions src/plugins/controls/session/preventConcurrency.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2023 (original work) Open Assessment Technologies SA ;
*/
import context from 'context';
import loggerFactory from 'core/logger';
import __ from 'i18n';
import states from 'taoQtiTest/runner/config/states';
import { getSequenceNumber, getSequenceStore } from 'taoQtiTest/runner/services/sequenceStore';
import pluginFactory from 'taoTests/runner/plugin';

const logger = loggerFactory('taoQtiTest/runner/plugins/controls/session/preventConcurrency');

const FEATURE_FLAG = 'FEATURE_FLAG_PAUSE_CONCURRENT_SESSIONS';

/**
* Test Runner Control Plugin : detect concurrent deliveries launched from the same user session.
*/
export default pluginFactory({
name: 'preventConcurrency',

/**
* Initializes the plugin (called during runner's init)
*/
init() {
const testRunner = this.getTestRunner();
const options = testRunner.getOptions();
const skipPausedAssessmentDialog = !!options.skipPausedAssessmentDialog;

return Promise.all([getSequenceNumber(testRunner), getSequenceStore()]).then(
([sequenceNumber, sequenceStore]) =>
sequenceStore.setSequenceNumber(sequenceNumber).then(() => {
testRunner
.on('tick', () => {
if (context.featureFlags[FEATURE_FLAG]) {
return sequenceStore.getSequenceNumber().then(lastSequenceNumber => {
if (lastSequenceNumber !== sequenceNumber) {
testRunner.off('tick');
testRunner.trigger('disabletools');
testRunner.trigger('disablenav');
testRunner.trigger('disableitem');
testRunner.trigger('concurrency');
return Promise.reject();
}
});
}
})
.on('concurrency', () => {
logger.warn(
`The sequence number has changed. Was another delivery opened in the same browser?`
);
testRunner.trigger('leave', {
code: states.testSession.suspended,
message: __(
'A concurrent delivery has been detected. Please use the last open session. The present window can be closed.'
),
skipExitMessage: skipPausedAssessmentDialog
});
});
})
);
}
});
59 changes: 59 additions & 0 deletions src/services/sequenceStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2023 (original work) Open Assessment Technologies SA ;
*/
import store from 'core/store';

const STORE_ID = 'current';
const SEQUENCE_NUMBER = 'sequence';

export default {
/**
* Creates a store for the sequence number for the session.
* @returns {Promise} - Resolved with the store API.
*/
getSequenceStore() {
return store(STORE_ID).then(sequenceStore => ({
/**
* Stores the sequence number for the session.
* @param {string} sequenceNumber - The new sequence number to set for the session.
* @returns {Promise} - Resolved once the sequence number has been stored.
*/
setSequenceNumber(sequenceNumber) {
return sequenceStore.setItem(SEQUENCE_NUMBER, sequenceNumber);
},

/**
* Reads the sequence number for the session from the storage.
* @returns {Promise<string>} - Resolved with the sequence number for the session.
*/
getSequenceNumber() {
return sequenceStore.getItem(SEQUENCE_NUMBER);
}
}));
},

/**
* Creates a sequence number for the test runner.
* @returns {Promise<string>} - Resolved with sequence number for the session.
*/
getSequenceNumber(testRunner) {
return testRunner
.getTestStore()
.getStorageIdentifier()
.then(storeId => `${storeId}-${Date.now()}`);
}
};
28 changes: 28 additions & 0 deletions test/plugins/controls/preventConcurrency/mocks/sequenceStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
define(function () {
('use strict');

let sequenceNumber = '';

return {
getSequenceStore() {
return Promise.resolve({
setSequenceNumber(seq) {
sequenceNumber = seq;
return Promise.resolve();
},

getSequenceNumber() {
return Promise.resolve(sequenceNumber);
}
});
},

getSequenceNumber(testRunner) {
return Promise.resolve(testRunner.sequenceNumber);
},

setSequenceNumber(seq) {
sequenceNumber = seq;
}
};
});
27 changes: 27 additions & 0 deletions test/plugins/controls/preventConcurrency/test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test Runner Plugins - preventConcurrency</title>
<script type="text/javascript" src="/environment/require.js"></script>
<script type="text/javascript">
require(['/environment/config.js'], function() {
require(['qunitEnv'], function() {
requirejs.config({
paths: {
'taoQtiTest/runner/services/sequenceStore': '/test/plugins/controls/preventConcurrency/mocks/sequenceStore'
}
});
require(['taoQtiTest/test/runner/plugins/controls/preventConcurrency/test'], function() {
QUnit.start();
});
});
});
</script>
</head>

<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
Loading

0 comments on commit 370a178

Please sign in to comment.