diff --git a/apps/files_sharing/js/external.js b/apps/files_sharing/js/external.js index aeb4b2461f..31407f28ff 100644 --- a/apps/files_sharing/js/external.js +++ b/apps/files_sharing/js/external.js @@ -44,7 +44,8 @@ {name: name, owner: owner, remote: remoteClean} ), t('files_sharing','Remote share'), - function (result) { + function (result, password) { + share.password = password; callback(result, share); }, true, @@ -62,72 +63,92 @@ $buttons.eq(0).text(t('core', 'Cancel')); $buttons.eq(1).text(t('files_sharing', 'Add remote share')); }; -})(); -$(document).ready(function () { - // 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(); + OCA.Sharing.ExternalShareDialogPlugin = { - //manually add server-to-server share - if (params.remote && params.token && params.owner && params.name) { + filesApp: null, - var callbackAddShare = function(result, share) { - var password = share.password || ''; - if (result) { - //$.post(OC.generateUrl('/apps/files_sharing/api/externalShares'), {id: share.id}); - $.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(); - } - }); - } - }; + attach: function(filesApp) { + this.filesApp = filesApp; + this.processIncomingShareFromUrl(); + this.processSharesToConfirm(); + }, - // 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 - ); - } + /** + * Process incoming remote share that might have been passed + * through the URL + */ + processIncomingShareFromUrl: function() { + var fileList = this.filesApp.fileList; + 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 - $.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(); + var callbackAddShare = function(result, share) { + var password = share.password || ''; + if (result) { + //$.post(OC.generateUrl('/apps/files_sharing/api/externalShares'), {id: share.id}); + $.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 { - // Delete - $.ajax({ - url: OC.generateUrl('/apps/files_sharing/api/externalShares/'+share.id), - type: 'DELETE' - }); + fileList.reload(); } - } + }); + } + }; + + // 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); -}); diff --git a/apps/files_sharing/tests/js/externalSpec.js b/apps/files_sharing/tests/js/externalSpec.js new file mode 100644 index 0000000000..2f8f4508d4 --- /dev/null +++ b/apps/files_sharing/tests/js/externalSpec.js @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015 Vincent Petry + * + * 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() + }); +}); diff --git a/tests/karma.config.js b/tests/karma.config.js index 414f155258..e4f8b3ea68 100644 --- a/tests/karma.config.js +++ b/tests/karma.config.js @@ -53,7 +53,8 @@ module.exports = function(config) { // up with the global namespace/classes/state 'apps/files_sharing/js/app.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'] },