Add unit test for external share JS dialog

Moved external share JS code into a small plugin to make it testable.

Added unit test for the external share dialog logic + ajax calls.
This commit is contained in:
Vincent Petry 2015-01-21 11:26:54 +01:00
parent 23ea45760f
commit f3d696599a
3 changed files with 202 additions and 58 deletions

View File

@ -63,72 +63,92 @@
$buttons.eq(0).text(t('core', 'Cancel')); $buttons.eq(0).text(t('core', 'Cancel'));
$buttons.eq(1).text(t('files_sharing', 'Add remote share')); $buttons.eq(1).text(t('files_sharing', 'Add remote share'));
}; };
})();
$(document).ready(function () { OCA.Sharing.ExternalShareDialogPlugin = {
// FIXME: HACK: do not init when running unit tests, need a better way
if (!window.TESTING && OCA.Files) {// only run in the files app
var params = OC.Util.History.parseUrlQuery();
//manually add server-to-server share filesApp: null,
if (params.remote && params.token && params.owner && params.name) {
var callbackAddShare = function(result, share) { attach: function(filesApp) {
var password = share.password || ''; this.filesApp = filesApp;
if (result) { this.processIncomingShareFromUrl();
//$.post(OC.generateUrl('/apps/files_sharing/api/externalShares'), {id: share.id}); this.processSharesToConfirm();
$.post(OC.generateUrl('apps/files_sharing/external'), { },
remote: share.remote,
token: share.token,
owner: share.owner,
name: share.name,
password: password}, function(result) {
if (result.status === 'error') {
OC.Notification.show(result.data.message);
} else {
FileList.reload();
}
});
}
};
// clear hash, it is unlikely that it contain any extra parameters /**
location.hash = ''; * Process incoming remote share that might have been passed
params.passwordProtected = parseInt(params.protected, 10) === 1; * through the URL
OCA.Sharing.showAddExternalDialog( */
params, processIncomingShareFromUrl: function() {
params.passwordProtected, var fileList = this.filesApp.fileList;
callbackAddShare var params = OC.Util.History.parseUrlQuery();
); //manually add server-to-server share
} if (params.remote && params.token && params.owner && params.name) {
// check for new server-to-server shares which need to be approved var callbackAddShare = function(result, share) {
$.get(OC.generateUrl('/apps/files_sharing/api/externalShares'), var password = share.password || '';
{}, if (result) {
function(shares) { //$.post(OC.generateUrl('/apps/files_sharing/api/externalShares'), {id: share.id});
var index; $.post(OC.generateUrl('apps/files_sharing/external'), {
for (index = 0; index < shares.length; ++index) { remote: share.remote,
OCA.Sharing.showAddExternalDialog( token: share.token,
shares[index], owner: share.owner,
false, name: share.name,
function(result, share) { password: password}, function(result) {
if (result) { if (result.status === 'error') {
// Accept OC.Notification.show(result.data.message);
$.post(OC.generateUrl('/apps/files_sharing/api/externalShares'), {id: share.id});
FileList.reload();
} else { } else {
// Delete fileList.reload();
$.ajax({
url: OC.generateUrl('/apps/files_sharing/api/externalShares/'+share.id),
type: 'DELETE'
});
} }
} });
}
};
// clear hash, it is unlikely that it contain any extra parameters
location.hash = '';
params.passwordProtected = parseInt(params.protected, 10) === 1;
OCA.Sharing.showAddExternalDialog(
params,
params.passwordProtected,
callbackAddShare
); );
} }
},
}); /**
* Retrieve a list of remote shares that need to be approved
*/
processSharesToConfirm: function() {
var fileList = this.filesApp.fileList;
// check for new server-to-server shares which need to be approved
$.get(OC.generateUrl('/apps/files_sharing/api/externalShares'),
{},
function(shares) {
var index;
for (index = 0; index < shares.length; ++index) {
OCA.Sharing.showAddExternalDialog(
shares[index],
false,
function(result, share) {
if (result) {
// Accept
$.post(OC.generateUrl('/apps/files_sharing/api/externalShares'), {id: share.id});
fileList.reload();
} else {
// Delete
$.ajax({
url: OC.generateUrl('/apps/files_sharing/api/externalShares/'+share.id),
type: 'DELETE'
});
}
}
);
}
} });
}
};
})();
OC.Plugins.register('OCA.Files.App', OCA.Sharing.ExternalShareDialogPlugin);
});

View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/
describe('OCA.Sharing external tests', function() {
var plugin;
var urlQueryStub;
var promptDialogStub;
var confirmDialogStub;
function dummyShowDialog() {
var deferred = $.Deferred();
deferred.resolve();
return deferred.promise();
}
beforeEach(function() {
plugin = OCA.Sharing.ExternalShareDialogPlugin;
urlQueryStub = sinon.stub(OC.Util.History, 'parseUrlQuery');
confirmDialogStub = sinon.stub(OC.dialogs, 'confirm', dummyShowDialog);
promptDialogStub = sinon.stub(OC.dialogs, 'prompt', dummyShowDialog);
plugin.filesApp = {
fileList: {
reload: sinon.stub()
}
}
});
afterEach(function() {
urlQueryStub.restore();
confirmDialogStub.restore();
promptDialogStub.restore();
plugin = null;
});
describe('confirmation dialog from URL', function() {
var testShare;
/**
* Checks that the server call's query matches what is
* expected.
*
* @param {Object} expectedQuery expected query params
*/
function checkRequest(expectedQuery) {
var request = fakeServer.requests[0];
var query = OC.parseQueryString(request.requestBody);
expect(request.method).toEqual('POST');
expect(query).toEqual(expectedQuery);
request.respond(
200,
{'Content-Type': 'application/json'},
JSON.stringify({status: 'success'})
);
expect(plugin.filesApp.fileList.reload.calledOnce).toEqual(true);
}
beforeEach(function() {
testShare = {
remote: 'http://example.com/owncloud',
token: 'abcdefg',
owner: 'theowner',
name: 'the share name'
};
});
it('does nothing when no share was passed in URL', function() {
urlQueryStub.returns({});
plugin.processIncomingShareFromUrl();
expect(promptDialogStub.notCalled).toEqual(true);
expect(confirmDialogStub.notCalled).toEqual(true);
expect(fakeServer.requests.length).toEqual(0);
});
it('sends share info to server on confirm', function() {
urlQueryStub.returns(testShare);
plugin.processIncomingShareFromUrl();
expect(promptDialogStub.notCalled).toEqual(true);
expect(confirmDialogStub.calledOnce).toEqual(true);
confirmDialogStub.getCall(0).args[2](true);
expect(fakeServer.requests.length).toEqual(1);
checkRequest({
remote: 'http://example.com/owncloud',
token: 'abcdefg',
owner: 'theowner',
name: 'the share name',
password: ''
});
});
it('sends share info with password to server on confirm', function() {
testShare = _.extend(testShare, {protected: 1});
urlQueryStub.returns(testShare);
plugin.processIncomingShareFromUrl();
expect(promptDialogStub.calledOnce).toEqual(true);
expect(confirmDialogStub.notCalled).toEqual(true);
promptDialogStub.getCall(0).args[2](true, 'thepassword');
expect(fakeServer.requests.length).toEqual(1);
checkRequest({
remote: 'http://example.com/owncloud',
token: 'abcdefg',
owner: 'theowner',
name: 'the share name',
password: 'thepassword'
});
});
it('does not send share info on cancel', function() {
urlQueryStub.returns(testShare);
plugin.processIncomingShareFromUrl();
expect(promptDialogStub.notCalled).toEqual(true);
expect(confirmDialogStub.calledOnce).toEqual(true);
confirmDialogStub.getCall(0).args[2](false);
expect(fakeServer.requests.length).toEqual(0);
});
});
describe('show dialog for each share to confirm', function() {
// TODO test plugin.processSharesToConfirm()
});
});

View File

@ -53,7 +53,8 @@ module.exports = function(config) {
// up with the global namespace/classes/state // up with the global namespace/classes/state
'apps/files_sharing/js/app.js', 'apps/files_sharing/js/app.js',
'apps/files_sharing/js/sharedfilelist.js', 'apps/files_sharing/js/sharedfilelist.js',
'apps/files_sharing/js/share.js' 'apps/files_sharing/js/share.js',
'apps/files_sharing/js/external.js'
], ],
testFiles: ['apps/files_sharing/tests/js/*.js'] testFiles: ['apps/files_sharing/tests/js/*.js']
}, },