UNPKG

@oat-sa/tao-test-runner-qti

Version:
120 lines (110 loc) 5.01 kB
define(['lodash', 'taoTests/runner/plugin', 'core/logger'], function (_, pluginFactory, loggerFactory) { 'use strict'; _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _; pluginFactory = pluginFactory && Object.prototype.hasOwnProperty.call(pluginFactory, 'default') ? pluginFactory['default'] : pluginFactory; loggerFactory = loggerFactory && Object.prototype.hasOwnProperty.call(loggerFactory, 'default') ? loggerFactory['default'] : loggerFactory; /** * 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) 2020 (original work) Open Assessment Technologies SA ; */ const logger = loggerFactory('taoQtiTest/runner/plugins/controls/duration/duration'); /** * Creates the timer plugin */ var duration = pluginFactory({ name: 'duration', /** * Install step, add behavior before the lifecycle. */ install() { // define the "duration" store as "volatile" (removed on browser change). this.getTestRunner().getTestStore().setVolatile(this.getName()); }, /** * Initializes the plugin (called during runner's init) * * @returns {Promise} */ init() { const testRunner = this.getTestRunner(); let currentUpdatePromise = Promise.resolve(); const getItemAttempt = () => { const context = testRunner.getTestContext(); return `${context.itemIdentifier}#${context.attempt}`; }; const getPositiveNumber = value => { if (!_.isNumber(value) || value < 0) { return 0; } return value; }; //where the duration of attempts are stored return testRunner.getPluginStore(this.getName()).then(durationStore => { /** * Gets the duration of a particular item from the store * * @param {String} attemptId - the attempt id to get the duration for * @returns {Promise} */ const getItemDuration = attemptId => { if (!/^(.*)+#+\d+$/.test(attemptId)) { return Promise.reject(new Error('Is it really an attempt id, like "itemid#attempt"')); } return durationStore.getItem(attemptId); }; /** * Updates the duration of a particular item * * @param {Number} elapsed - time elapsed since previous tick * @returns {Promise} */ const updateDuration = elapsed => { const itemAttemptId = getItemAttempt(); currentUpdatePromise = currentUpdatePromise.then(() => getItemDuration(itemAttemptId)).then(duration => durationStore.setItem(itemAttemptId, getPositiveNumber(duration) + getPositiveNumber(elapsed) / 1000)).catch(err => { logger.warn(`Error updating item duration! ${err && err.message}`); }); return currentUpdatePromise; }; /** * Adds the current duration to the next action request. * The duration will be sent to the server with the next request, * usually submitItem() or callItemAction() * * @returns {Promise} */ const addDurationToCallActionParams = () => { const itemAttemptId = getItemAttempt(); return currentUpdatePromise.then(() => getItemDuration(itemAttemptId)).then(duration => testRunner.getProxy().addCallActionParams({ itemDuration: getPositiveNumber(duration) })).catch(err => { logger.warn(`Error retrieving item duration! ${err && err.message}`); }); }; //change plugin state testRunner.on('tick', updateDuration).before('move skip exit timeout pause', addDurationToCallActionParams) /** * @event duration.get * @param {String} attemptId - the attempt id to get the duration for * @param {getDuration} getDuration - a receiver callback */.on('plugin-get.duration', (attemptId, getDuration) => { if (_.isFunction(getDuration)) { getDuration(getItemDuration(attemptId)); } }); }); } }); return duration; });