From fa7996aa8aad67992556ba8f64cb4d7ada0d44f8 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 23 Dec 2015 10:16:57 +0100 Subject: [PATCH 1/4] Web sharing uses sharee endpoint --- core/js/sharedialogview.js | 90 +++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 15 deletions(-) diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index dd07adceac..b8d07bad99 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -117,22 +117,82 @@ var $loading = this.$el.find('.shareWithLoading'); $loading.removeClass('hidden'); $loading.addClass('inlineblock'); - $.get(OC.filePath('core', 'ajax', 'share.php'), { - fetch: 'getShareWith', - search: search.term.trim(), - limit: 200, - itemShares: OC.Share.itemShares, - itemType: view.model.get('itemType') - }, function (result) { - $loading.addClass('hidden'); - $loading.removeClass('inlineblock'); - if (result.status == 'success' && result.data.length > 0) { - $('.shareWithField').autocomplete("option", "autoFocus", true); - response(result.data); - } else { - response(); + $.get( + OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees', + { + format: 'json', + search: search.term.trim(), + perPage: 200, + itemType: view.model.get('itemType') + }, + function (result) { + $loading.addClass('hidden'); + $loading.removeClass('inlineblock'); + if (result.ocs.meta.statuscode == 100) { + var users = [].concat(result.ocs.data.exact.users).concat(result.ocs.data.users); + var groups = result.ocs.data.exact.groups.concat(result.ocs.data.groups); + var remotes = result.ocs.data.exact.remotes.concat(result.ocs.data.remotes); + + var usersLength; + var groupsLength; + var remotesLength; + + var i, j; + + //Filter out the current user + usersLength = users.length; + for (i = 0 ; i < usersLength; i++) { + if (users[i].value.shareWith === OC.currentUser) { + users.splice(i, 1); + break; + } + } + + // Filter out the owner of the share + + var shares = view.model.get('shares'); + var sharesLength = shares.length; + + // Now filter out all sharees that are already shared with + for (i = 0; i < sharesLength; i++) { + var share = shares[i]; + + if (share.share_type === OC.Share.SHARE_TYPE_USER) { + usersLength = users.length; + for (j = 0; j < usersLength; j++) { + if (users[j].value.shareWith === share.share_with) { + users.splice(j, 1); + break; + } + } + } else if (share.share_type === OC.Share.SHARE_TYPE_GROUP) { + groupsLength = groups.length; + for (j = 0; j < groupsLength; j++) { + if (groups[j].value.shareWith === share.share_with) { + groups.splice(j, 1); + break; + } + } + } else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE) { + remotesLength = remotes.length; + for (j = 0; j < remotesLength; j++) { + if (remotes[j].value.shareWith === share.share_with) { + remotes.splice(j, 1); + break; + } + } + } + } + + var suggestions = users.concat(groups).concat(remotes); + + $('.shareWithField').autocomplete("option", "autoFocus", true); + response(suggestions); + } else { + response(); + } } - }).fail(function () { + ).fail(function() { $loading.addClass('hidden'); $loading.removeClass('inlineblock'); OC.Notification.show(t('core', 'An error occured. Please try again')); From f99fcd5dd6ccd0013016d8db068451e31385d3b1 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 23 Dec 2015 10:38:53 +0100 Subject: [PATCH 2/4] Filter out share owner in sharee suggestion list --- core/js/sharedialogview.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index b8d07bad99..c89c1d95be 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -149,6 +149,15 @@ } // Filter out the owner of the share + if (view.model.hasReshare()) { + usersLength = users.length; + for (i = 0 ; i < usersLength; i++) { + if (users[i].value.shareWith === view.model.getReshareOwner()) { + users.splice(i, 1); + break; + } + } + } var shares = view.model.get('shares'); var sharesLength = shares.length; From 49031e07443a18efb7246c005076c427b535e201 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 23 Dec 2015 10:49:27 +0100 Subject: [PATCH 3/4] Fix unit tests --- core/js/sharedialogview.js | 10 +++++--- core/js/tests/specs/sharedialogviewSpec.js | 30 +++++++++++++++++++--- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index c89c1d95be..4cebf7962e 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -129,7 +129,7 @@ $loading.addClass('hidden'); $loading.removeClass('inlineblock'); if (result.ocs.meta.statuscode == 100) { - var users = [].concat(result.ocs.data.exact.users).concat(result.ocs.data.users); + var users = result.ocs.data.exact.users.concat(result.ocs.data.users); var groups = result.ocs.data.exact.groups.concat(result.ocs.data.groups); var remotes = result.ocs.data.exact.remotes.concat(result.ocs.data.remotes); @@ -195,8 +195,12 @@ var suggestions = users.concat(groups).concat(remotes); - $('.shareWithField').autocomplete("option", "autoFocus", true); - response(suggestions); + if (suggestions.length > 0) { + $('.shareWithField').autocomplete("option", "autoFocus", true); + response(suggestions); + } else { + response(); + } } else { response(); } diff --git a/core/js/tests/specs/sharedialogviewSpec.js b/core/js/tests/specs/sharedialogviewSpec.js index bfd3d98786..2a2be72c21 100644 --- a/core/js/tests/specs/sharedialogviewSpec.js +++ b/core/js/tests/specs/sharedialogviewSpec.js @@ -724,15 +724,30 @@ describe('OC.Share.ShareDialogView', function() { var response = sinon.stub(); dialog.autocompleteHandler({term: 'bob'}, response); var jsonData = JSON.stringify({ - "data": [{"label": "bob", "value": {"shareType": 0, "shareWith": "test"}}], - "status": "success" + 'ocs' : { + 'meta' : { + 'status' : 'success', + 'statuscode' : 100, + 'message' : null + }, + 'data' : { + 'exact' : { + 'users' : [], + 'groups' : [], + 'remotes': [] + }, + 'users' : [{'label': 'bob', 'value': {'shareType': 0, 'shareWith': 'test'}}], + 'groups' : [], + 'remotes': [] + } + } }); fakeServer.requests[0].respond( 200, {'Content-Type': 'application/json'}, jsonData ); - expect(response.calledWithExactly(JSON.parse(jsonData).data)).toEqual(true); + expect(response.calledWithExactly(JSON.parse(jsonData).ocs.data.users)).toEqual(true); expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); }); @@ -740,7 +755,14 @@ describe('OC.Share.ShareDialogView', function() { dialog.render(); var response = sinon.stub(); dialog.autocompleteHandler({term: 'bob'}, response); - var jsonData = JSON.stringify({"status": "failure"}); + var jsonData = JSON.stringify({ + 'ocs' : { + 'meta' : { + 'status': 'failure', + 'statuscode': 400 + } + } + }); fakeServer.requests[0].respond( 200, {'Content-Type': 'application/json'}, From 6bd15856b2204cbfde3ab130dd0eb38ab3e0c06e Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 30 Dec 2015 10:46:19 +0100 Subject: [PATCH 4/4] Added js tests for the Sharee API usage --- core/js/tests/specs/sharedialogviewSpec.js | 292 +++++++++++++++++++++ 1 file changed, 292 insertions(+) diff --git a/core/js/tests/specs/sharedialogviewSpec.js b/core/js/tests/specs/sharedialogviewSpec.js index 2a2be72c21..63cfe5299a 100644 --- a/core/js/tests/specs/sharedialogviewSpec.js +++ b/core/js/tests/specs/sharedialogviewSpec.js @@ -702,6 +702,7 @@ describe('OC.Share.ShareDialogView', function() { }); }); }); + describe('remote sharing', function() { it('shows remote share info when allowed', function() { configModel.set({ @@ -751,6 +752,297 @@ describe('OC.Share.ShareDialogView', function() { expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); }); + describe('filter out', function() { + it('the current user', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'bob'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': 0, + 'shareWith': OC.currentUser + } + }, + { + 'label': 'bobby', + 'value': { + 'shareType': 0, + 'shareWith': 'imbob' + } + } + ], + 'groups': [], + 'remotes': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'bobby', + 'value': {'shareType': 0, 'shareWith': 'imbob'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('the share owner', function () { + shareModel.set({ + reshare: { + uid_owner: 'user1' + }, + shares: [], + permissions: OC.PERMISSION_READ + }); + + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'bob'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': 0, + 'shareWith': 'user1' + } + }, + { + 'label': 'bobby', + 'value': { + 'shareType': 0, + 'shareWith': 'imbob' + } + } + ], + 'groups': [], + 'remotes': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'bobby', + 'value': {'shareType': 0, 'shareWith': 'imbob'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + describe('already shared with', function () { + beforeEach(function() { + shareModel.set({ + reshare: {}, + shares: [{ + id: 100, + item_source: 123, + permissions: 31, + share_type: OC.Share.SHARE_TYPE_USER, + share_with: 'user1', + share_with_displayname: 'User One' + },{ + id: 101, + item_source: 123, + permissions: 31, + share_type: OC.Share.SHARE_TYPE_GROUP, + share_with: 'group', + share_with_displayname: 'group' + },{ + id: 102, + item_source: 123, + permissions: 31, + share_type: OC.Share.SHARE_TYPE_REMOTE, + share_with: 'foo@bar.com/baz', + share_with_displayname: 'foo@bar.com/baz' + + }] + }); + }); + + it('users', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'bob'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + }, + { + 'label': 'bobby', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'imbob' + } + } + ], + 'groups': [], + 'remotes': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'bobby', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('groups', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'group'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [ + { + 'label': 'group', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'group' + } + }, + { + 'label': 'group2', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'group2' + } + } + ], + 'remotes': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'group2', + 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group2'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('remotes', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'bob'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [], + 'remotes': [ + { + 'label': 'foo@bar.com/baz', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_REMOTE, + 'shareWith': 'foo@bar.com/baz' + } + }, + { + 'label': 'foo2@bar.com/baz', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_REMOTE, + 'shareWith': 'foo2@bar.com/baz' + } + } + ] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'foo2@bar.com/baz', + 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo2@bar.com/baz'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + }); + }); + it('gracefully handles successful ajax call with failure content', function () { dialog.render(); var response = sinon.stub();