Updated unit tests for file actions and actions menu

This commit is contained in:
Vincent Petry 2015-08-05 12:48:42 +02:00
parent dd4e0a8253
commit 9454e9043a
5 changed files with 618 additions and 317 deletions

View File

@ -332,10 +332,8 @@
* @param {OCA.Files.FileActionContext} context rendering context * @param {OCA.Files.FileActionContext} context rendering context
*/ */
_showMenu: function(fileName, context) { _showMenu: function(fileName, context) {
var $actionEl = context.$file.find('.action-menu');
this._menu = new OCA.Files.FileActionsMenu(); this._menu = new OCA.Files.FileActionsMenu();
this._menu.showAt($actionEl, context); this._menu.showAt(context);
}, },
/** /**
@ -433,7 +431,7 @@
nameLinks = parent.children('a.name'); nameLinks = parent.children('a.name');
nameLinks.find('.fileactions, .nametext .action').remove(); nameLinks.find('.fileactions, .nametext .action').remove();
nameLinks.append('<span class="fileactions" />'); nameLinks.append('<span class="fileactions" />');
var defaultAction = this.getDefault( var defaultAction = this.getDefaultFileAction(
this.getCurrentMimeType(), this.getCurrentMimeType(),
this.getCurrentType(), this.getCurrentType(),
this.getCurrentPermissions() this.getCurrentPermissions()
@ -449,7 +447,7 @@
if (actionSpec.type === FileActions.TYPE_INLINE) { if (actionSpec.type === FileActions.TYPE_INLINE) {
self._renderInlineAction( self._renderInlineAction(
actionSpec, actionSpec,
actionSpec.action === defaultAction, defaultAction && actionSpec.name === defaultAction.name,
context context
); );
} }

View File

@ -42,7 +42,7 @@
/** /**
* @private * @private
*/ */
initialize: function(fileActions, fileList) { initialize: function() {
this.$el = $('<div class="fileActionsMenu dropdown hidden menu"></div>'); this.$el = $('<div class="fileActionsMenu dropdown hidden menu"></div>');
this._template = Handlebars.compile(TEMPLATE_MENU); this._template = Handlebars.compile(TEMPLATE_MENU);
@ -50,6 +50,10 @@
this.$el.on('afterHide', _.bind(this._onHide, this)); this.$el.on('afterHide', _.bind(this._onHide, this));
}, },
destroy: function() {
this.$el.remove();
},
/** /**
* Event handler whenever an action has been clicked within the menu * Event handler whenever an action has been clicked within the menu
* *
@ -118,17 +122,15 @@
/** /**
* Displays the menu under the given element * Displays the menu under the given element
* *
* @param {Object} $el target element
* @param {OCA.Files.FileActionContext} context context * @param {OCA.Files.FileActionContext} context context
*/ */
showAt: function($el, context) { showAt: function(context) {
this._context = context; this._context = context;
this.render(); this.render();
this.$el.removeClass('hidden'); this.$el.removeClass('hidden');
$el.closest('td').append(this.$el); context.$file.find('td.filename').append(this.$el);
context.$file.addClass('mouseOver'); context.$file.addClass('mouseOver');
OC.showMenu(null, this.$el); OC.showMenu(null, this.$el);
@ -139,7 +141,7 @@
*/ */
_onHide: function() { _onHide: function() {
this._context.$file.removeClass('mouseOver'); this._context.$file.removeClass('mouseOver');
this.$el.remove(); this.destroy();
} }
}; };

View File

@ -20,8 +20,7 @@
*/ */
describe('OCA.Files.FileActions tests', function() { describe('OCA.Files.FileActions tests', function() {
var $filesTable, fileList; var fileList, fileActions;
var FileActions;
beforeEach(function() { beforeEach(function() {
// init horrible parameters // init horrible parameters
@ -29,211 +28,175 @@ describe('OCA.Files.FileActions tests', function() {
$body.append('<input type="hidden" id="dir" value="/subdir"></input>'); $body.append('<input type="hidden" id="dir" value="/subdir"></input>');
$body.append('<input type="hidden" id="permissions" value="31"></input>'); $body.append('<input type="hidden" id="permissions" value="31"></input>');
// dummy files table // dummy files table
$filesTable = $body.append('<table id="filestable"></table>'); fileActions = new OCA.Files.FileActions();
fileList = new OCA.Files.FileList($('#testArea')); fileActions.registerAction({
FileActions = new OCA.Files.FileActions(); name: 'Testdropdown',
FileActions.registerDefaultActions(); displayName: 'Testdropdowndisplay',
mime: 'all',
permissions: OC.PERMISSION_READ,
icon: function () {
return OC.imagePath('core', 'actions/download');
}
});
fileActions.registerAction({
name: 'Testinline',
displayName: 'Testinlinedisplay',
type: OCA.Files.FileActions.TYPE_INLINE,
mime: 'all',
permissions: OC.PERMISSION_READ
});
fileActions.registerAction({
name: 'Testdefault',
displayName: 'Testdefaultdisplay',
mime: 'all',
permissions: OC.PERMISSION_READ
});
fileActions.setDefault('all', 'Testdefault');
fileList = new OCA.Files.FileList($body, {
fileActions: fileActions
});
}); });
afterEach(function() { afterEach(function() {
FileActions = null; fileActions = null;
fileList.destroy(); fileList.destroy();
fileList = undefined; fileList = undefined;
$('#dir, #permissions, #filestable').remove(); $('#dir, #permissions, #filestable').remove();
}); });
it('calling clear() clears file actions', function() { it('calling clear() clears file actions', function() {
FileActions.clear(); fileActions.clear();
expect(FileActions.actions).toEqual({}); expect(fileActions.actions).toEqual({});
expect(FileActions.defaults).toEqual({}); expect(fileActions.defaults).toEqual({});
expect(FileActions.icons).toEqual({}); expect(fileActions.icons).toEqual({});
expect(FileActions.currentFile).toBe(null); expect(fileActions.currentFile).toBe(null);
}); });
it('calling display() sets file actions', function() { describe('displaying actions', function() {
var fileData = { var $tr;
id: 18,
type: 'file',
name: 'testName.txt',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
// note: FileActions.display() is called implicitly beforeEach(function() {
var $tr = fileList.add(fileData); var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456',
permissions: OC.PERMISSION_READ | OC.PERMISSION_UPDATE
};
// actions defined after call // note: FileActions.display() is called implicitly
expect($tr.find('.action.action-download').length).toEqual(1); $tr = fileList.add(fileData);
expect($tr.find('.action.action-download').attr('data-action')).toEqual('Download'); });
expect($tr.find('.nametext .action.action-rename').length).toEqual(1); it('renders inline file actions', function() {
expect($tr.find('.nametext .action.action-rename').attr('data-action')).toEqual('Rename'); // actions defined after call
expect($tr.find('.action.delete').length).toEqual(1); expect($tr.find('.action.action-testinline').length).toEqual(1);
expect($tr.find('.action.action-testinline').attr('data-action')).toEqual('Testinline');
});
it('does not render dropdown actions', function() {
expect($tr.find('.action.action-testdropdown').length).toEqual(0);
});
it('does not render default action', function() {
expect($tr.find('.action.action-testdefault').length).toEqual(0);
});
it('replaces file actions when displayed twice', function() {
fileActions.display($tr.find('td.filename'), true, fileList);
fileActions.display($tr.find('td.filename'), true, fileList);
expect($tr.find('.action.action-testinline').length).toEqual(1);
});
it('renders actions menu trigger', function() {
expect($tr.find('.action.action-menu').length).toEqual(1);
expect($tr.find('.action.action-menu').attr('data-action')).toEqual('menu');
});
it('only renders actions relevant to the mime type', function() {
fileActions.registerAction({
name: 'Match',
displayName: 'MatchDisplay',
type: OCA.Files.FileActions.TYPE_INLINE,
mime: 'text/plain',
permissions: OC.PERMISSION_READ
});
fileActions.registerAction({
name: 'Nomatch',
displayName: 'NoMatchDisplay',
type: OCA.Files.FileActions.TYPE_INLINE,
mime: 'application/octet-stream',
permissions: OC.PERMISSION_READ
});
fileActions.display($tr.find('td.filename'), true, fileList);
expect($tr.find('.action.action-match').length).toEqual(1);
expect($tr.find('.action.action-nomatch').length).toEqual(0);
});
it('only renders actions relevant to the permissions', function() {
fileActions.registerAction({
name: 'Match',
displayName: 'MatchDisplay',
type: OCA.Files.FileActions.TYPE_INLINE,
mime: 'text/plain',
permissions: OC.PERMISSION_UPDATE
});
fileActions.registerAction({
name: 'Nomatch',
displayName: 'NoMatchDisplay',
type: OCA.Files.FileActions.TYPE_INLINE,
mime: 'text/plain',
permissions: OC.PERMISSION_DELETE
});
fileActions.display($tr.find('td.filename'), true, fileList);
expect($tr.find('.action.action-match').length).toEqual(1);
expect($tr.find('.action.action-nomatch').length).toEqual(0);
});
}); });
it('calling display() twice correctly replaces file actions', function() { describe('action handler', function() {
var fileData = { var actionStub, $tr;
id: 18,
type: 'file',
name: 'testName.txt',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
var $tr = fileList.add(fileData);
FileActions.display($tr.find('td.filename'), true, fileList); beforeEach(function() {
FileActions.display($tr.find('td.filename'), true, fileList); var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
actionStub = sinon.stub();
fileActions.registerAction({
name: 'Test',
type: OCA.Files.FileActions.TYPE_INLINE,
mime: 'all',
icon: OC.imagePath('core', 'actions/test'),
permissions: OC.PERMISSION_READ,
actionHandler: actionStub
});
$tr = fileList.add(fileData);
});
it('passes context to action handler', function() {
$tr.find('.action-test').click();
expect(actionStub.calledOnce).toEqual(true);
expect(actionStub.getCall(0).args[0]).toEqual('testName.txt');
var context = actionStub.getCall(0).args[1];
expect(context.$file.is($tr)).toEqual(true);
expect(context.fileList).toBeDefined();
expect(context.fileActions).toBeDefined();
expect(context.dir).toEqual('/subdir');
// actions defined after cal // when data-path is defined
expect($tr.find('.action.action-download').length).toEqual(1); actionStub.reset();
expect($tr.find('.nametext .action.action-rename').length).toEqual(1); $tr.attr('data-path', '/somepath');
expect($tr.find('.action.delete').length).toEqual(1); $tr.find('.action-test').click();
}); context = actionStub.getCall(0).args[1];
it('redirects to download URL when clicking download', function() { expect(context.dir).toEqual('/somepath');
var redirectStub = sinon.stub(OC, 'redirect'); });
var fileData = { it('shows actions menu when clicking the menu trigger', function() {
id: 18, expect($tr.find('.menu').length).toEqual(0);
type: 'file', $tr.find('.action-menu').click();
name: 'testName.txt', expect($tr.find('.menu').length).toEqual(1);
mimetype: 'text/plain', });
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
var $tr = fileList.add(fileData);
FileActions.display($tr.find('td.filename'), true, fileList);
$tr.find('.action-download').click();
expect(redirectStub.calledOnce).toEqual(true);
expect(redirectStub.getCall(0).args[0]).toContain(
OC.webroot +
'/index.php/apps/files/ajax/download.php' +
'?dir=%2Fsubdir&files=testName.txt');
redirectStub.restore();
});
it('takes the file\'s path into account when clicking download', function() {
var redirectStub = sinon.stub(OC, 'redirect');
var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
path: '/anotherpath/there',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
var $tr = fileList.add(fileData);
FileActions.display($tr.find('td.filename'), true, fileList);
$tr.find('.action-download').click();
expect(redirectStub.calledOnce).toEqual(true);
expect(redirectStub.getCall(0).args[0]).toContain(
OC.webroot + '/index.php/apps/files/ajax/download.php' +
'?dir=%2Fanotherpath%2Fthere&files=testName.txt'
);
redirectStub.restore();
});
it('deletes file when clicking delete', function() {
var deleteStub = sinon.stub(fileList, 'do_delete');
var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
path: '/somepath/dir',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
var $tr = fileList.add(fileData);
FileActions.display($tr.find('td.filename'), true, fileList);
$tr.find('.action.delete').click();
expect(deleteStub.calledOnce).toEqual(true);
expect(deleteStub.getCall(0).args[0]).toEqual('testName.txt');
expect(deleteStub.getCall(0).args[1]).toEqual('/somepath/dir');
deleteStub.restore();
});
it('shows delete hint when no permission to delete', function() {
var deleteStub = sinon.stub(fileList, 'do_delete');
var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
path: '/somepath/dir',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456',
permissions: OC.PERMISSION_READ
};
var $tr = fileList.add(fileData);
FileActions.display($tr.find('td.filename'), true, fileList);
var $action = $tr.find('.action.delete');
expect($action.hasClass('no-permission')).toEqual(true);
deleteStub.restore();
});
it('shows delete hint not when permission to delete', function() {
var deleteStub = sinon.stub(fileList, 'do_delete');
var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
path: '/somepath/dir',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456',
permissions: OC.PERMISSION_DELETE
};
var $tr = fileList.add(fileData);
FileActions.display($tr.find('td.filename'), true, fileList);
var $action = $tr.find('.action.delete');
expect($action.hasClass('no-permission')).toEqual(false);
deleteStub.restore();
});
it('passes context to action handler', function() {
var actionStub = sinon.stub();
var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
var $tr = fileList.add(fileData);
FileActions.register(
'all',
'Test',
OC.PERMISSION_READ,
OC.imagePath('core', 'actions/test'),
actionStub
);
FileActions.display($tr.find('td.filename'), true, fileList);
$tr.find('.action-test').click();
expect(actionStub.calledOnce).toEqual(true);
expect(actionStub.getCall(0).args[0]).toEqual('testName.txt');
var context = actionStub.getCall(0).args[1];
expect(context.$file.is($tr)).toEqual(true);
expect(context.fileList).toBeDefined();
expect(context.fileActions).toBeDefined();
expect(context.dir).toEqual('/subdir');
// when data-path is defined
actionStub.reset();
$tr.attr('data-path', '/somepath');
$tr.find('.action-test').click();
context = actionStub.getCall(0).args[1];
expect(context.dir).toEqual('/somepath');
}); });
describe('custom rendering', function() { describe('custom rendering', function() {
var $tr; var $tr;
@ -251,10 +214,11 @@ describe('OCA.Files.FileActions tests', function() {
}); });
it('regular function', function() { it('regular function', function() {
var actionStub = sinon.stub(); var actionStub = sinon.stub();
FileActions.registerAction({ fileActions.registerAction({
name: 'Test', name: 'Test',
displayName: '', displayName: '',
mime: 'all', mime: 'all',
type: OCA.Files.FileActions.TYPE_INLINE,
permissions: OC.PERMISSION_READ, permissions: OC.PERMISSION_READ,
render: function(actionSpec, isDefault, context) { render: function(actionSpec, isDefault, context) {
expect(actionSpec.name).toEqual('Test'); expect(actionSpec.name).toEqual('Test');
@ -266,13 +230,13 @@ describe('OCA.Files.FileActions tests', function() {
expect(context.fileList).toEqual(fileList); expect(context.fileList).toEqual(fileList);
expect(context.$file[0]).toEqual($tr[0]); expect(context.$file[0]).toEqual($tr[0]);
var $customEl = $('<a href="#"><span>blabli</span><span>blabla</span></a>'); var $customEl = $('<a class="action action-test" href="#"><span>blabli</span><span>blabla</span></a>');
$tr.find('td:first').append($customEl); $tr.find('td:first').append($customEl);
return $customEl; return $customEl;
}, },
actionHandler: actionStub actionHandler: actionStub
}); });
FileActions.display($tr.find('td.filename'), true, fileList); fileActions.display($tr.find('td.filename'), true, fileList);
var $actionEl = $tr.find('td:first .action-test'); var $actionEl = $tr.find('td:first .action-test');
expect($actionEl.length).toEqual(1); expect($actionEl.length).toEqual(1);
@ -306,20 +270,22 @@ describe('OCA.Files.FileActions tests', function() {
var actions2 = new OCA.Files.FileActions(); var actions2 = new OCA.Files.FileActions();
var actionStub1 = sinon.stub(); var actionStub1 = sinon.stub();
var actionStub2 = sinon.stub(); var actionStub2 = sinon.stub();
actions1.register( actions1.registerAction({
'all', name: 'Test',
'Test', type: OCA.Files.FileActions.TYPE_INLINE,
OC.PERMISSION_READ, mime: 'all',
OC.imagePath('core', 'actions/test'), permissions: OC.PERMISSION_READ,
actionStub1 icon: OC.imagePath('core', 'actions/test'),
); actionHandler: actionStub1
actions2.register( });
'all', actions2.registerAction({
'Test2', name: 'Test2',
OC.PERMISSION_READ, type: OCA.Files.FileActions.TYPE_INLINE,
OC.imagePath('core', 'actions/test'), mime: 'all',
actionStub2 permissions: OC.PERMISSION_READ,
); icon: OC.imagePath('core', 'actions/test'),
actionHandler: actionStub2
});
actions2.merge(actions1); actions2.merge(actions1);
actions2.display($tr.find('td.filename'), true, fileList); actions2.display($tr.find('td.filename'), true, fileList);
@ -342,20 +308,22 @@ describe('OCA.Files.FileActions tests', function() {
var actions2 = new OCA.Files.FileActions(); var actions2 = new OCA.Files.FileActions();
var actionStub1 = sinon.stub(); var actionStub1 = sinon.stub();
var actionStub2 = sinon.stub(); var actionStub2 = sinon.stub();
actions1.register( actions1.registerAction({
'all', name: 'Test',
'Test', type: OCA.Files.FileActions.TYPE_INLINE,
OC.PERMISSION_READ, mime: 'all',
OC.imagePath('core', 'actions/test'), permissions: OC.PERMISSION_READ,
actionStub1 icon: OC.imagePath('core', 'actions/test'),
); actionHandler: actionStub1
actions2.register( });
'all', actions2.registerAction({
'Test', // override name: 'Test', // override
OC.PERMISSION_READ, mime: 'all',
OC.imagePath('core', 'actions/test'), type: OCA.Files.FileActions.TYPE_INLINE,
actionStub2 permissions: OC.PERMISSION_READ,
); icon: OC.imagePath('core', 'actions/test'),
actionHandler: actionStub2
});
actions1.merge(actions2); actions1.merge(actions2);
actions1.display($tr.find('td.filename'), true, fileList); actions1.display($tr.find('td.filename'), true, fileList);
@ -371,24 +339,26 @@ describe('OCA.Files.FileActions tests', function() {
var actions2 = new OCA.Files.FileActions(); var actions2 = new OCA.Files.FileActions();
var actionStub1 = sinon.stub(); var actionStub1 = sinon.stub();
var actionStub2 = sinon.stub(); var actionStub2 = sinon.stub();
actions1.register( actions1.registerAction({
'all', mime: 'all',
'Test', name: 'Test',
OC.PERMISSION_READ, type: OCA.Files.FileActions.TYPE_INLINE,
OC.imagePath('core', 'actions/test'), permissions: OC.PERMISSION_READ,
actionStub1 icon: OC.imagePath('core', 'actions/test'),
); actionHandler: actionStub1
});
actions1.merge(actions2); actions1.merge(actions2);
// late override // late override
actions1.register( actions1.registerAction({
'all', mime: 'all',
'Test', // override name: 'Test', // override
OC.PERMISSION_READ, type: OCA.Files.FileActions.TYPE_INLINE,
OC.imagePath('core', 'actions/test'), permissions: OC.PERMISSION_READ,
actionStub2 icon: OC.imagePath('core', 'actions/test'),
); actionHandler: actionStub2
});
actions1.display($tr.find('td.filename'), true, fileList); actions1.display($tr.find('td.filename'), true, fileList);
@ -403,25 +373,27 @@ describe('OCA.Files.FileActions tests', function() {
var actions2 = new OCA.Files.FileActions(); var actions2 = new OCA.Files.FileActions();
var actionStub1 = sinon.stub(); var actionStub1 = sinon.stub();
var actionStub2 = sinon.stub(); var actionStub2 = sinon.stub();
actions1.register( actions1.registerAction({
'all', mime: 'all',
'Test', name: 'Test',
OC.PERMISSION_READ, type: OCA.Files.FileActions.TYPE_INLINE,
OC.imagePath('core', 'actions/test'), permissions: OC.PERMISSION_READ,
actionStub1 icon: OC.imagePath('core', 'actions/test'),
); actionHandler: actionStub1
});
// copy the Test action to actions2 // copy the Test action to actions2
actions2.merge(actions1); actions2.merge(actions1);
// late override // late override
actions2.register( actions2.registerAction({
'all', mime: 'all',
'Test', // override name: 'Test', // override
OC.PERMISSION_READ, type: OCA.Files.FileActions.TYPE_INLINE,
OC.imagePath('core', 'actions/test'), permissions: OC.PERMISSION_READ,
actionStub2 icon: OC.imagePath('core', 'actions/test'),
); actionHandler: actionStub2
});
// check if original actions still call the correct handler // check if original actions still call the correct handler
actions1.display($tr.find('td.filename'), true, fileList); actions1.display($tr.find('td.filename'), true, fileList);
@ -444,42 +416,45 @@ describe('OCA.Files.FileActions tests', function() {
it('notifies update event handlers once after multiple changes', function() { it('notifies update event handlers once after multiple changes', function() {
var actionStub = sinon.stub(); var actionStub = sinon.stub();
var handler = sinon.stub(); var handler = sinon.stub();
FileActions.on('registerAction', handler); fileActions.on('registerAction', handler);
FileActions.register( fileActions.registerAction({
'all', mime: 'all',
'Test', name: 'Test',
OC.PERMISSION_READ, type: OCA.Files.FileActions.TYPE_INLINE,
OC.imagePath('core', 'actions/test'), permissions: OC.PERMISSION_READ,
actionStub icon: OC.imagePath('core', 'actions/test'),
); actionHandler: actionStub
FileActions.register( });
'all', fileActions.registerAction({
'Test2', mime: 'all',
OC.PERMISSION_READ, name: 'Test2',
OC.imagePath('core', 'actions/test'), permissions: OC.PERMISSION_READ,
actionStub icon: OC.imagePath('core', 'actions/test'),
); actionHandler: actionStub
});
expect(handler.calledTwice).toEqual(true); expect(handler.calledTwice).toEqual(true);
}); });
it('does not notifies update event handlers after unregistering', function() { it('does not notifies update event handlers after unregistering', function() {
var actionStub = sinon.stub(); var actionStub = sinon.stub();
var handler = sinon.stub(); var handler = sinon.stub();
FileActions.on('registerAction', handler); fileActions.on('registerAction', handler);
FileActions.off('registerAction', handler); fileActions.off('registerAction', handler);
FileActions.register( fileActions.registerAction({
'all', mime: 'all',
'Test', name: 'Test',
OC.PERMISSION_READ, type: OCA.Files.FileActions.TYPE_INLINE,
OC.imagePath('core', 'actions/test'), permissions: OC.PERMISSION_READ,
actionStub icon: OC.imagePath('core', 'actions/test'),
); actionHandler: actionStub
FileActions.register( });
'all', fileActions.registerAction({
'Test2', mime: 'all',
OC.PERMISSION_READ, name: 'Test2',
OC.imagePath('core', 'actions/test'), type: OCA.Files.FileActions.TYPE_INLINE,
actionStub permissions: OC.PERMISSION_READ,
); icon: OC.imagePath('core', 'actions/test'),
actionHandler: actionStub
});
expect(handler.notCalled).toEqual(true); expect(handler.notCalled).toEqual(true);
}); });
}); });

View File

@ -0,0 +1,291 @@
/**
* ownCloud
*
* @author Vincent Petry
* @copyright 2015 Vincent Petry <pvince81@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
describe('OCA.Files.FileActionsMenu tests', function() {
var fileList, fileActions, menu, actionStub, $tr;
beforeEach(function() {
// init horrible parameters
var $body = $('#testArea');
$body.append('<input type="hidden" id="dir" value="/subdir"></input>');
$body.append('<input type="hidden" id="permissions" value="31"></input>');
// dummy files table
actionStub = sinon.stub();
fileActions = new OCA.Files.FileActions();
fileList = new OCA.Files.FileList($body, {
fileActions: fileActions
});
fileActions.registerAction({
name: 'Testdropdown',
displayName: 'Testdropdowndisplay',
mime: 'all',
permissions: OC.PERMISSION_READ,
icon: function () {
return OC.imagePath('core', 'actions/download');
},
actionHandler: actionStub
});
fileActions.registerAction({
name: 'Testdropdownnoicon',
displayName: 'Testdropdowndisplaynoicon',
mime: 'all',
permissions: OC.PERMISSION_READ,
actionHandler: actionStub
});
fileActions.registerAction({
name: 'Testinline',
displayName: 'Testinlinedisplay',
type: OCA.Files.FileActions.TYPE_INLINE,
mime: 'all',
permissions: OC.PERMISSION_READ
});
fileActions.registerAction({
name: 'Testdefault',
displayName: 'Testdefaultdisplay',
mime: 'all',
permissions: OC.PERMISSION_READ
});
fileActions.setDefault('all', 'Testdefault');
var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
$tr = fileList.add(fileData);
var menuContext = {
$file: $tr,
fileList: fileList,
fileActions: fileActions,
dir: fileList.getCurrentDirectory()
};
menu = new OCA.Files.FileActionsMenu();
menu.showAt(menuContext);
});
afterEach(function() {
fileActions = null;
fileList.destroy();
fileList = undefined;
menu.destroy();
$('#dir, #permissions, #filestable').remove();
});
describe('rendering', function() {
it('displays menu in the row container', function() {
expect(menu.$el.closest('td.filename').length).toEqual(1);
expect($tr.find('.fileActionsMenu').length).toEqual(1);
});
it('highlights the row in the file list', function() {
expect($tr.hasClass('mouseOver')).toEqual(true);
});
it('renders dropdown actions in menu', function() {
var $action = menu.$el.find('a[data-action=Testdropdown]');
expect($action.length).toEqual(1);
expect($action.find('img').attr('src'))
.toEqual(OC.imagePath('core', 'actions/download'));
expect($action.find('.no-icon').length).toEqual(0);
$action = menu.$el.find('a[data-action=Testdropdownnoicon]');
expect($action.length).toEqual(1);
expect($action.find('img').length).toEqual(0);
expect($action.find('.no-icon').length).toEqual(1);
});
it('does not render default actions', function() {
expect(menu.$el.find('a[data-action=Testdefault]').length).toEqual(0);
});
it('does not render inline actions', function() {
expect(menu.$el.find('a[data-action=Testinline]').length).toEqual(0);
});
it('only renders actions relevant to the mime type', function() {
fileActions.registerAction({
name: 'Match',
displayName: 'MatchDisplay',
mime: 'text/plain',
permissions: OC.PERMISSION_READ
});
fileActions.registerAction({
name: 'Nomatch',
displayName: 'NoMatchDisplay',
mime: 'application/octet-stream',
permissions: OC.PERMISSION_READ
});
menu.render();
expect(menu.$el.find('a[data-action=Match]').length).toEqual(1);
expect(menu.$el.find('a[data-action=NoMatch]').length).toEqual(0);
});
it('only renders actions relevant to the permissions', function() {
fileActions.registerAction({
name: 'Match',
displayName: 'MatchDisplay',
mime: 'text/plain',
permissions: OC.PERMISSION_UPDATE
});
fileActions.registerAction({
name: 'Nomatch',
displayName: 'NoMatchDisplay',
mime: 'text/plain',
permissions: OC.PERMISSION_DELETE
});
menu.render();
expect(menu.$el.find('a[data-action=Match]').length).toEqual(1);
expect(menu.$el.find('a[data-action=NoMatch]').length).toEqual(0);
});
});
describe('action handler', function() {
it('calls action handler when clicking menu item', function() {
var $action = menu.$el.find('a[data-action=Testdropdown]');
$action.click();
expect(actionStub.calledOnce).toEqual(true);
expect(actionStub.getCall(0).args[0]).toEqual('testName.txt');
expect(actionStub.getCall(0).args[1].$file[0]).toEqual($tr[0]);
expect(actionStub.getCall(0).args[1].fileList).toEqual(fileList);
expect(actionStub.getCall(0).args[1].fileActions).toEqual(fileActions);
expect(actionStub.getCall(0).args[1].dir).toEqual('/subdir');
});
});
describe('default actions from registerDefaultActions', function() {
beforeEach(function() {
fileActions.clear();
fileActions.registerDefaultActions();
});
it('redirects to download URL when clicking download', function() {
var redirectStub = sinon.stub(OC, 'redirect');
var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
var $tr = fileList.add(fileData);
fileActions.display($tr.find('td.filename'), true, fileList);
var menuContext = {
$file: $tr,
fileList: fileList,
fileActions: fileActions,
dir: fileList.getCurrentDirectory()
};
menu = new OCA.Files.FileActionsMenu();
menu.showAt(menuContext);
menu.$el.find('.action-download').click();
expect(redirectStub.calledOnce).toEqual(true);
expect(redirectStub.getCall(0).args[0]).toContain(
OC.webroot +
'/index.php/apps/files/ajax/download.php' +
'?dir=%2Fsubdir&files=testName.txt');
redirectStub.restore();
});
it('takes the file\'s path into account when clicking download', function() {
var redirectStub = sinon.stub(OC, 'redirect');
var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
path: '/anotherpath/there',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
var $tr = fileList.add(fileData);
fileActions.display($tr.find('td.filename'), true, fileList);
var menuContext = {
$file: $tr,
fileList: fileList,
fileActions: fileActions,
dir: '/anotherpath/there'
};
menu = new OCA.Files.FileActionsMenu();
menu.showAt(menuContext);
menu.$el.find('.action-download').click();
expect(redirectStub.calledOnce).toEqual(true);
expect(redirectStub.getCall(0).args[0]).toContain(
OC.webroot + '/index.php/apps/files/ajax/download.php' +
'?dir=%2Fanotherpath%2Fthere&files=testName.txt'
);
redirectStub.restore();
});
it('deletes file when clicking delete', function() {
var deleteStub = sinon.stub(fileList, 'do_delete');
var fileData = {
id: 18,
type: 'file',
name: 'testName.txt',
path: '/somepath/dir',
mimetype: 'text/plain',
size: '1234',
etag: 'a01234c',
mtime: '123456'
};
var $tr = fileList.add(fileData);
fileActions.display($tr.find('td.filename'), true, fileList);
var menuContext = {
$file: $tr,
fileList: fileList,
fileActions: fileActions,
dir: '/somepath/dir'
};
menu = new OCA.Files.FileActionsMenu();
menu.showAt(menuContext);
menu.$el.find('.action-delete').click();
expect(deleteStub.calledOnce).toEqual(true);
expect(deleteStub.getCall(0).args[0]).toEqual('testName.txt');
expect(deleteStub.getCall(0).args[1]).toEqual('/somepath/dir');
deleteStub.restore();
});
});
describe('hiding', function() {
beforeEach(function() {
menu.$el.trigger(new $.Event('afterHide'));
});
it('removes highlight on current row', function() {
expect($tr.hasClass('mouseOver')).toEqual(false);
});
it('destroys its DOM element on hide', function() {
expect($tr.find('.fileActionsMenu').length).toEqual(0);
});
});
});

View File

@ -456,19 +456,19 @@ describe('OCA.Files.FileList tests', function() {
expect(notificationStub.notCalled).toEqual(true); expect(notificationStub.notCalled).toEqual(true);
}); });
it('shows spinner on files to be deleted', function() { it('shows busy state on files to be deleted', function() {
fileList.setFiles(testFiles); fileList.setFiles(testFiles);
doDelete(); doDelete();
expect(fileList.findFileEl('One.txt').find('.icon-loading-small:not(.icon-delete)').length).toEqual(1); expect(fileList.findFileEl('One.txt').hasClass('busy')).toEqual(true);
expect(fileList.findFileEl('Three.pdf').find('.icon-delete:not(.icon-loading-small)').length).toEqual(1); expect(fileList.findFileEl('Three.pdf').hasClass('busy')).toEqual(false);
}); });
it('shows spinner on all files when deleting all', function() { it('shows busy state on all files when deleting all', function() {
fileList.setFiles(testFiles); fileList.setFiles(testFiles);
fileList.do_delete(); fileList.do_delete();
expect(fileList.$fileList.find('tr .icon-loading-small:not(.icon-delete)').length).toEqual(4); expect(fileList.$fileList.find('tr.busy').length).toEqual(4);
}); });
it('updates summary when deleting last file', function() { it('updates summary when deleting last file', function() {
var $summary; var $summary;
@ -625,7 +625,7 @@ describe('OCA.Files.FileList tests', function() {
doCancelRename(); doCancelRename();
expect($summary.find('.info').text()).toEqual('1 folder and 3 files'); expect($summary.find('.info').text()).toEqual('1 folder and 3 files');
}); });
it('Hides actions while rename in progress', function() { it('Shows busy state while rename in progress', function() {
var $tr; var $tr;
doRename(); doRename();
@ -634,8 +634,7 @@ describe('OCA.Files.FileList tests', function() {
expect($tr.length).toEqual(1); expect($tr.length).toEqual(1);
expect(fileList.findFileEl('One.txt').length).toEqual(0); expect(fileList.findFileEl('One.txt').length).toEqual(0);
// file actions are hidden // file actions are hidden
expect($tr.find('.action').hasClass('hidden')).toEqual(true); expect($tr.hasClass('busy')).toEqual(true);
expect($tr.find('.fileactions').hasClass('hidden')).toEqual(true);
// input and form are gone // input and form are gone
expect(fileList.$fileList.find('input.filename').length).toEqual(0); expect(fileList.$fileList.find('input.filename').length).toEqual(0);
@ -1918,16 +1917,17 @@ describe('OCA.Files.FileList tests', function() {
it('Clicking on a file name will trigger default action', function() { it('Clicking on a file name will trigger default action', function() {
var actionStub = sinon.stub(); var actionStub = sinon.stub();
fileList.setFiles(testFiles); fileList.setFiles(testFiles);
fileList.fileActions.register( fileList.fileActions.registerAction({
'text/plain', mime: 'text/plain',
'Test', name: 'Test',
OC.PERMISSION_ALL, type: OCA.Files.FileActions.TYPE_INLINE,
function() { permissions: OC.PERMISSION_ALL,
icon: function() {
// Specify icon for hitory button // Specify icon for hitory button
return OC.imagePath('core','actions/history'); return OC.imagePath('core','actions/history');
}, },
actionStub actionHandler: actionStub
); });
fileList.fileActions.setDefault('text/plain', 'Test'); fileList.fileActions.setDefault('text/plain', 'Test');
var $tr = fileList.findFileEl('One.txt'); var $tr = fileList.findFileEl('One.txt');
$tr.find('td.filename .nametext').click(); $tr.find('td.filename .nametext').click();
@ -1958,16 +1958,17 @@ describe('OCA.Files.FileList tests', function() {
fileList.$fileList.on('fileActionsReady', readyHandler); fileList.$fileList.on('fileActionsReady', readyHandler);
fileList.fileActions.register( fileList.fileActions.registerAction({
'text/plain', mime: 'text/plain',
'Test', name: 'Test',
OC.PERMISSION_ALL, type: OCA.Files.FileActions.TYPE_INLINE,
function() { permissions: OC.PERMISSION_ALL,
icon: function() {
// Specify icon for hitory button // Specify icon for hitory button
return OC.imagePath('core','actions/history'); return OC.imagePath('core','actions/history');
}, },
actionStub actionHandler: actionStub
); });
var $tr = fileList.findFileEl('One.txt'); var $tr = fileList.findFileEl('One.txt');
expect($tr.find('.action-test').length).toEqual(0); expect($tr.find('.action-test').length).toEqual(0);
expect(readyHandler.notCalled).toEqual(true); expect(readyHandler.notCalled).toEqual(true);
@ -2256,6 +2257,8 @@ describe('OCA.Files.FileList tests', function() {
}); });
}); });
describe('Handeling errors', function () { describe('Handeling errors', function () {
var redirectStub;
beforeEach(function () { beforeEach(function () {
redirectStub = sinon.stub(OC, 'redirect'); redirectStub = sinon.stub(OC, 'redirect');
@ -2281,4 +2284,36 @@ describe('OCA.Files.FileList tests', function() {
expect(redirectStub.calledWith(OC.generateUrl('apps/files'))).toEqual(true); expect(redirectStub.calledWith(OC.generateUrl('apps/files'))).toEqual(true);
}); });
}); });
describe('showFileBusyState', function() {
var $tr;
beforeEach(function() {
fileList.setFiles(testFiles);
$tr = fileList.findFileEl('Two.jpg');
});
it('shows spinner on busy rows', function() {
fileList.showFileBusyState('Two.jpg', true);
expect($tr.hasClass('busy')).toEqual(true);
expect(OC.TestUtil.getImageUrl($tr.find('.thumbnail')))
.toEqual(OC.imagePath('core', 'loading.gif'));
fileList.showFileBusyState('Two.jpg', false);
expect($tr.hasClass('busy')).toEqual(false);
expect(OC.TestUtil.getImageUrl($tr.find('.thumbnail')))
.toEqual(OC.imagePath('core', 'filetypes/image.svg'));
});
it('accepts multiple input formats', function() {
_.each([
'Two.jpg',
['Two.jpg'],
$tr,
[$tr]
], function(testCase) {
fileList.showFileBusyState(testCase, true);
expect($tr.hasClass('busy')).toEqual(true);
fileList.showFileBusyState(testCase, false);
expect($tr.hasClass('busy')).toEqual(false);
});
});
});
}); });