243 lines
8.5 KiB
JavaScript
243 lines
8.5 KiB
JavaScript
/*
|
|
* 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) 2018 (original work) Open Assessment Technlogies SA
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Test the module {@link layout/actions}
|
|
*
|
|
* @author Bertrand Chevrier <bertrand@taotesting.com>
|
|
*/
|
|
define(['jquery', 'layout/actions', 'layout/actions/binder'], function($, actionsManager, binder) {
|
|
'use strict';
|
|
|
|
QUnit.module('API');
|
|
|
|
QUnit.test('module', function(assert) {
|
|
assert.ok(typeof actionsManager === 'object', 'The module expose a plain object');
|
|
});
|
|
|
|
QUnit.cases.init([
|
|
{title: 'on'},
|
|
{title: 'off'},
|
|
{title: 'trigger'},
|
|
{title: 'before'},
|
|
{title: 'after'},
|
|
{title: 'removeAllListeners'}
|
|
]).test('Eventifier API ', function(data, assert) {
|
|
assert.equal(typeof actionsManager[data.title], 'function', 'The module exposes the eventifier method "' + data.title);
|
|
});
|
|
|
|
QUnit.cases.init([
|
|
{title: 'init'},
|
|
{title: 'updateState'},
|
|
{title: 'updateContext'},
|
|
{title: 'exec'},
|
|
{title: 'getBy'}
|
|
]).test('Instance API ', function(data, assert) {
|
|
assert.equal(typeof actionsManager[data.title], 'function', 'The module exposes the method "' + data.title + '"');
|
|
});
|
|
|
|
QUnit.module('Behavior', {
|
|
afterEach: function(assert) {
|
|
actionsManager.removeAllListeners();
|
|
}
|
|
});
|
|
|
|
QUnit.test('Load actions and update context', function(assert) {
|
|
|
|
assert.expect(10);
|
|
|
|
assert.equal(actionsManager.getBy('foo-new'), null, 'The foo-new action is not bound');
|
|
assert.equal(actionsManager.getBy('foo-delete'), null, 'The foo-delete action is not bound');
|
|
assert.equal(actionsManager.getBy('foo-special'), null, 'The foo-special action is not bound');
|
|
|
|
actionsManager.init($('#qunit-fixture'));
|
|
|
|
assert.deepEqual(actionsManager.getBy('foo-new'), {
|
|
id: 'foo-new',
|
|
name: 'New Foo',
|
|
binding: 'addFoo',
|
|
url: 'https://foo.org/taoFoo/Foo/new',
|
|
context: 'resource',
|
|
multiple: false,
|
|
rights: {id: 'WRITE'},
|
|
state: {
|
|
disabled: false,
|
|
hidden: true,
|
|
active: false
|
|
}
|
|
}, 'The foo-new action is now bound');
|
|
assert.deepEqual(actionsManager.getBy('foo-delete'), {
|
|
id: 'foo-delete',
|
|
name: 'Delete',
|
|
binding: 'deleteFoo',
|
|
url: 'https://foo.org/taoFoo/Foo/delete',
|
|
context: 'instance',
|
|
multiple: false,
|
|
rights: {id: 'WRITE'},
|
|
state: {
|
|
disabled: false,
|
|
hidden: true,
|
|
active: false
|
|
}
|
|
}, 'The foo-delete action is now bound');
|
|
assert.deepEqual(actionsManager.getBy('foo-special'), {
|
|
id: 'foo-special',
|
|
name: 'Special',
|
|
binding: 'special',
|
|
url: 'https://foo.org/taoFoo/Foo/special',
|
|
context: 'class',
|
|
multiple: false,
|
|
rights: { },
|
|
state: {
|
|
disabled: true,
|
|
hidden: true,
|
|
active: false
|
|
}
|
|
}, 'The foo-special action is now bound');
|
|
|
|
actionsManager.updateContext({
|
|
type: 'instance',
|
|
uri: 'https://foo.org/Foo#123'
|
|
});
|
|
|
|
assert.equal(actionsManager.getBy('foo-new').state.hidden, false, 'The new action is now visible');
|
|
assert.equal(actionsManager.getBy('foo-delete').state.hidden, false, 'The delete action is now visible');
|
|
assert.equal(actionsManager.getBy('foo-special').state.hidden, true, 'The special action is not visible');
|
|
assert.equal(actionsManager.getBy('foo-special').state.disabled, true, 'The special action remains disabled');
|
|
});
|
|
|
|
QUnit.test('execute an action', function(assert) {
|
|
var ready = assert.async();
|
|
var context = {
|
|
type: 'instance',
|
|
uri: 'https://foo.org/Foo#123'
|
|
};
|
|
|
|
assert.expect(4);
|
|
|
|
binder.register('addFoo', function(receivedContext) {
|
|
|
|
assert.deepEqual(this, {
|
|
id: 'foo-new',
|
|
name: 'New Foo',
|
|
binding: 'addFoo',
|
|
url: 'https://foo.org/taoFoo/Foo/new',
|
|
context: 'resource',
|
|
multiple: false,
|
|
rights: {id: 'WRITE'},
|
|
state: {
|
|
disabled: false,
|
|
hidden: false,
|
|
active: true
|
|
}
|
|
}, 'The executed action has the actionContext as lexical scope');
|
|
assert.deepEqual(context, receivedContext, 'The received context matches the current');
|
|
return new Promise(function(resolve) {
|
|
setTimeout(resolve, 10);
|
|
});
|
|
});
|
|
|
|
actionsManager.init($('#qunit-fixture'));
|
|
actionsManager.updateContext(context);
|
|
|
|
actionsManager
|
|
.on('foo-new', function(receivedContext) {
|
|
assert.deepEqual(context, receivedContext, 'The received context matches the current');
|
|
})
|
|
.on('error', function(err) {
|
|
assert.ok(false, err.message);
|
|
ready();
|
|
})
|
|
.exec('foo-new')
|
|
.then(function() {
|
|
assert.ok(true, 'exec always return a resolved promise');
|
|
ready();
|
|
});
|
|
});
|
|
|
|
QUnit.test('cancel an action', function(assert) {
|
|
var ready = assert.async();
|
|
|
|
assert.expect(3);
|
|
|
|
binder.register('deleteFoo', function() {
|
|
return new Promise(function(resolve, reject) {
|
|
assert.ok(true, 'The delete action is executed');
|
|
setTimeout(function() {
|
|
reject({cancel: true});
|
|
}, 10);
|
|
});
|
|
});
|
|
|
|
actionsManager.init($('#qunit-fixture'));
|
|
actionsManager
|
|
.on('foo-delete', function() {
|
|
assert.ok(false, 'The action is canceled so the event should not be triggered');
|
|
ready();
|
|
})
|
|
.on('error', function() {
|
|
assert.ok(false, 'The action is canceled so the error event should not be triggered');
|
|
ready();
|
|
})
|
|
.on('cancel', function(actionId) {
|
|
assert.equal(actionId, 'foo-delete', 'The correct action has been canceled');
|
|
})
|
|
.exec('foo-delete')
|
|
.then(function() {
|
|
assert.ok(true, 'exec always return a resolved promise');
|
|
ready();
|
|
});
|
|
});
|
|
|
|
QUnit.test('fail an action', function(assert) {
|
|
var ready = assert.async();
|
|
|
|
assert.expect(4);
|
|
|
|
binder.register('deleteFoo', function() {
|
|
return new Promise(function(resolve, reject) {
|
|
assert.ok(true, 'The delete action is executed');
|
|
setTimeout(function() {
|
|
reject(new TypeError('out of bound'));
|
|
}, 10);
|
|
});
|
|
});
|
|
|
|
actionsManager.init($('#qunit-fixture'));
|
|
actionsManager
|
|
.on('foo-delete', function() {
|
|
assert.ok(false, 'The action fail so the action event should not be triggered');
|
|
ready();
|
|
})
|
|
.on('error', function(err) {
|
|
assert.ok(err instanceof TypeError, 'The action rejects with the correct error.');
|
|
assert.equal(err.message, 'out of bound', 'The error message matches.');
|
|
})
|
|
.on('cancel', function() {
|
|
assert.ok(false, 'The action should not cancel');
|
|
ready();
|
|
})
|
|
.exec('foo-delete')
|
|
.then(function() {
|
|
assert.ok(true, 'exec always return a resolved promise, even if failed');
|
|
ready();
|
|
});
|
|
});
|
|
});
|