diff options
Diffstat (limited to 'core/js/tests/specs/sharedialogviewSpec.js')
-rw-r--r-- | core/js/tests/specs/sharedialogviewSpec.js | 1570 |
1 files changed, 1528 insertions, 42 deletions
diff --git a/core/js/tests/specs/sharedialogviewSpec.js b/core/js/tests/specs/sharedialogviewSpec.js index c6d5793623c..d3639159849 100644 --- a/core/js/tests/specs/sharedialogviewSpec.js +++ b/core/js/tests/specs/sharedialogviewSpec.js @@ -30,7 +30,6 @@ describe('OC.Share.ShareDialogView', function() { var saveLinkShareStub; var fetchStub; - var notificationStub; var configModel; var shareModel; @@ -472,54 +471,728 @@ describe('OC.Share.ShareDialogView', function() { }); }); }); - describe('remote sharing', function() { - it('shows remote share info when allowed', function() { - configModel.set({ - isRemoteShareAllowed: true + describe('get suggestions', function() { + it('no matches', function() { + var doneStub = sinon.stub(); + var failStub = sinon.stub(); + + dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); + + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } }); - dialog.render(); - expect(dialog.$el.find('.shareWithRemoteInfo').length).toEqual(1); + + expect(doneStub.called).toEqual(false); + expect(failStub.called).toEqual(false); + + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(doneStub.calledOnce).toEqual(true); + expect(doneStub.calledWithExactly([], [])).toEqual(true); + expect(failStub.called).toEqual(false); }); - it('does not show remote share info when not allowed', function() { - configModel.set({ - isRemoteShareAllowed: false + it('single partial match', function() { + var doneStub = sinon.stub(); + var failStub = sinon.stub(); + + dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); + + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [ + { + 'label': 'bobby', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'imbob' + } + } + ], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } }); - dialog.render(); - expect(dialog.$el.find('.shareWithRemoteInfo').length).toEqual(0); + + expect(doneStub.called).toEqual(false); + expect(failStub.called).toEqual(false); + + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(doneStub.calledOnce).toEqual(true); + expect(doneStub.calledWithExactly([{ + 'label': 'bobby', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'} + }], [ + ])).toEqual(true); + expect(failStub.called).toEqual(false); }); - }); - describe('autocompletion of users', function() { - it('triggers autocomplete display and focus with data when ajax search succeeds', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'bob'}, response); + it('single exact match', function() { + var doneStub = sinon.stub(); + var failStub = sinon.stub(); + + dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); + var jsonData = JSON.stringify({ - 'ocs' : { - 'meta' : { - 'status' : 'success', - 'statuscode' : 100, - 'message' : null + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + } + ], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } + }); + + expect(doneStub.called).toEqual(false); + expect(failStub.called).toEqual(false); + + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(doneStub.calledOnce).toEqual(true); + expect(doneStub.calledWithExactly([{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }], [{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }])).toEqual(true); + expect(failStub.called).toEqual(false); + }); + it('mixed matches', function() { + var doneStub = sinon.stub(); + var failStub = sinon.stub(); + + dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); + + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + } + ], + 'groups': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'group1' + } + } + ], + 'remotes': [] + }, + 'users': [ + { + 'label': 'bobby', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'imbob' + } + }, + { + 'label': 'bob the second', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user2' + } + } + ], + 'groups': [ + { + 'label': 'bobfans', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'fans' + } + } + ], + 'remotes': [], + 'lookup': [] + } + } + }); + + expect(doneStub.called).toEqual(false); + expect(failStub.called).toEqual(false); + + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(doneStub.calledOnce).toEqual(true); + expect(doneStub.calledWithExactly([{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }, { + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'} + }, { + 'label': 'bobby', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'} + }, { + 'label': 'bob the second', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user2'} + }, { + 'label': 'bobfans', + 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'fans'} + }], [{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }, { + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'} + }])).toEqual(true); + expect(failStub.called).toEqual(false); + }); + + it('does not send a request to the server again for the same parameters', function() { + var doneStub = sinon.stub(); + var failStub = sinon.stub(); + + dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); + + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null }, - 'data' : { - 'exact' : { - 'users' : [], - 'groups' : [], + 'data': { + 'exact': { + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + } + ], + 'groups': [], 'remotes': [] }, - 'users' : [{'label': 'bob', 'value': {'shareType': 0, 'shareWith': 'test'}}], - 'groups' : [], + 'users': [], + 'groups': [], 'remotes': [], 'lookup': [] } } }); + + expect(doneStub.called).toEqual(false); + expect(failStub.called).toEqual(false); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(doneStub.calledOnce).toEqual(true); + expect(doneStub.calledWithExactly([{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }], [{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }])).toEqual(true); + expect(failStub.called).toEqual(false); + + var done2Stub = sinon.stub(); + var fail2Stub = sinon.stub(); + + dialog._getSuggestions('bob', 42, shareModel).done(done2Stub).fail(fail2Stub); + + expect(doneStub.calledOnce).toEqual(true); + expect(failStub.called).toEqual(false); + + expect(done2Stub.calledOnce).toEqual(true); + expect(done2Stub.calledWithExactly([{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }], [{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }])).toEqual(true); + expect(fail2Stub.called).toEqual(false); + }); + + it('sends a request to the server again for the same parameters if the calls are not consecutive', function() { + var doneStub = sinon.stub(); + var failStub = sinon.stub(); + + dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); + + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + } + ], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } + }); + + expect(doneStub.called).toEqual(false); + expect(failStub.called).toEqual(false); + + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(doneStub.calledOnce).toEqual(true); + expect(doneStub.calledWithExactly([{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }], [{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }])).toEqual(true); + expect(failStub.called).toEqual(false); + + var done2Stub = sinon.stub(); + var fail2Stub = sinon.stub(); + + dialog._getSuggestions('bob', 108, shareModel).done(done2Stub).fail(fail2Stub); + + expect(done2Stub.called).toEqual(false); + expect(fail2Stub.called).toEqual(false); + + fakeServer.requests[1].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(done2Stub.calledOnce).toEqual(true); + expect(fail2Stub.called).toEqual(false); + + var done3Stub = sinon.stub(); + var fail3Stub = sinon.stub(); + + dialog._getSuggestions('bob', 42, shareModel).done(done3Stub).fail(fail3Stub); + + expect(done3Stub.called).toEqual(false); + expect(fail3Stub.called).toEqual(false); + + fakeServer.requests[2].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(doneStub.calledOnce).toEqual(true); + expect(failStub.called).toEqual(false); + expect(done2Stub.calledOnce).toEqual(true); + expect(fail2Stub.called).toEqual(false); + + expect(done3Stub.calledOnce).toEqual(true); + expect(done3Stub.calledWithExactly([{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }], [{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }])).toEqual(true); + expect(fail3Stub.called).toEqual(false); + }); + }); + describe('autocompletion of users', function() { + var showTemporaryNotificationStub; + + beforeEach(function() { + showTemporaryNotificationStub = sinon.stub(OC.Notification, 'show'); + }); + + afterEach(function() { + showTemporaryNotificationStub.restore(); + }); + + describe('triggers autocomplete display and focus with data when ajax search succeeds', function () { + 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': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + } + ], + 'groups': [], + 'remotes': [] + }, + 'users': [ + { + 'label': 'bobby', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'imbob' + } + } + ], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } + }); + fakeServer.requests[0].respond( 200, {'Content-Type': 'application/json'}, jsonData - ); - expect(response.calledWithExactly(JSON.parse(jsonData).ocs.data.users)).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + ); + expect(response.calledWithExactly([{ + 'label': 'bob', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} + }, { + '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': [ + { + 'label': 'group', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'group' + } + } + ], + 'remotes': [] + }, + 'users': [], + 'groups': [ + { + 'label': 'group2', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'group2' + } + } + ], + 'remotes': [], + 'lookup': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'group', + 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group'} + }, { + '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: 'foo@bar.com/baz'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [ + { + 'label': 'foo@bar.com/baz', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_REMOTE, + 'shareWith': 'foo@bar.com/baz' + } + } + ] + }, + 'users': [], + 'groups': [], + 'remotes': [ + { + 'label': 'foo@bar.com/baz2', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_REMOTE, + 'shareWith': 'foo@bar.com/baz2' + } + } + ], + 'lookup': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'foo@bar.com/baz', + 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo@bar.com/baz'} + }, { + 'label': 'foo@bar.com/baz2', + 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo@bar.com/baz2'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('emails', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'foo@bar.com'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [], + 'emails': [ + { + 'label': 'foo@bar.com', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_EMAIL, + 'shareWith': 'foo@bar.com' + } + } + ] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [], + 'emails': [ + { + 'label': 'foo@bar.com2', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_EMAIL, + 'shareWith': 'foo@bar.com2' + } + } + ] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'foo@bar.com', + 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo@bar.com'} + }, { + 'label': 'foo@bar.com2', + 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo@bar.com2'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('circles', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'CircleName'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [], + 'circles': [ + { + 'label': 'CircleName (type, owner)', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_CIRCLE, + 'shareWith': 'shortId' + } + }, + { + 'label': 'CircleName (type2, owner)', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_CIRCLE, + 'shareWith': 'shortId2' + } + } + ] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [], + 'circles': [ + { + 'label': 'CircleName2 (type, owner)', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_CIRCLE, + 'shareWith': 'shortId3' + } + } + ] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'CircleName (type, owner)', + 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId'} + }, { + 'label': 'CircleName (type2, owner)', + 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId2'} + }, { + 'label': 'CircleName2 (type, owner)', + 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId3'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); }); describe('filter out', function() { @@ -658,7 +1331,20 @@ describe('OC.Share.ShareDialogView', function() { share_type: OC.Share.SHARE_TYPE_REMOTE, share_with: 'foo@bar.com/baz', share_with_displayname: 'foo@bar.com/baz' - + },{ + id: 103, + item_source: 123, + permissions: 31, + share_type: OC.Share.SHARE_TYPE_EMAIL, + share_with: 'foo@bar.com', + share_with_displayname: 'foo@bar.com' + },{ + id: 104, + item_source: 123, + permissions: 31, + share_type: OC.Share.SHARE_TYPE_CIRCLE, + share_with: 'shortId', + share_with_displayname: 'CircleName (type, owner)' }] }); }); @@ -666,7 +1352,7 @@ describe('OC.Share.ShareDialogView', function() { it('users', function () { dialog.render(); var response = sinon.stub(); - dialog.autocompleteHandler({term: 'bob'}, response); + dialog.autocompleteHandler({term: 'bo'}, response); var jsonData = JSON.stringify({ 'ocs': { 'meta': { @@ -714,10 +1400,62 @@ describe('OC.Share.ShareDialogView', function() { expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); }); + it('users (exact)', 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': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + } + ], + 'groups': [], + 'remotes': [] + }, + 'users': [ + { + 'label': 'bobby', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'imbob' + } + } + ], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } + }); + 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); + dialog.autocompleteHandler({term: 'grou'}, response); var jsonData = JSON.stringify({ 'ocs': { 'meta': { @@ -765,10 +1503,62 @@ describe('OC.Share.ShareDialogView', function() { expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); }); + it('groups (exact)', 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': [ + { + 'label': 'group', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'group' + } + } + ], + 'remotes': [] + }, + 'users': [], + 'groups': [ + { + 'label': 'group2', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'group2' + } + } + ], + 'remotes': [], + 'lookup': [] + } + } + }); + 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); + dialog.autocompleteHandler({term: 'foo'}, response); var jsonData = JSON.stringify({ 'ocs': { 'meta': { @@ -815,10 +1605,286 @@ describe('OC.Share.ShareDialogView', function() { }])).toEqual(true); expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); }); + + it('remotes (exact)', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'foo@bar.com/baz'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [ + { + 'label': 'foo@bar.com/baz', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_REMOTE, + 'shareWith': 'foo@bar.com/baz' + } + } + ] + }, + 'users': [], + 'groups': [], + 'remotes': [ + { + 'label': 'foo@bar.com/baz2', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_REMOTE, + 'shareWith': 'foo@bar.com/baz2' + } + } + ], + 'lookup': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'foo@bar.com/baz2', + 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo@bar.com/baz2'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('emails', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'foo'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [], + 'emails': [] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [], + 'emails': [ + { + 'label': 'foo@bar.com', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_EMAIL, + 'shareWith': 'foo@bar.com' + } + }, + { + 'label': 'foo2@bar.com', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_EMAIL, + 'shareWith': 'foo2@bar.com' + } + } + ] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'foo2@bar.com', + 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo2@bar.com'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('emails (exact)', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'foo@bar.com'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [], + 'emails': [ + { + 'label': 'foo@bar.com', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_EMAIL, + 'shareWith': 'foo@bar.com' + } + } + ] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [], + 'emails': [ + { + 'label': 'foo@bar.com2', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_EMAIL, + 'shareWith': 'foo@bar.com2' + } + } + ] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'foo@bar.com2', + 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo@bar.com2'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('circles', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'CircleNam'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [], + 'circles': [] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [], + 'circles': [ + { + 'label': 'CircleName (type, owner)', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_CIRCLE, + 'shareWith': 'shortId' + } + }, + { + 'label': 'CircleName (type2, owner)', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_CIRCLE, + 'shareWith': 'shortId2' + } + } + ] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'CircleName (type2, owner)', + 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId2'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('circles (exact)', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'CircleName'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [], + 'circles': [ + { + 'label': 'CircleName (type, owner)', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_CIRCLE, + 'shareWith': 'shortId' + } + }, + { + 'label': 'CircleName (type2, owner)', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_CIRCLE, + 'shareWith': 'shortId2' + } + } + ] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [], + 'circles': [ + { + 'label': 'CircleName2 (type, owner)', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_CIRCLE, + 'shareWith': 'shortId3' + } + } + ] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'CircleName (type2, owner)', + 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId2'} + }, { + 'label': 'CircleName2 (type, owner)', + 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId3'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); }); }); - it('gracefully handles successful ajax call with failure content', function () { + it('throws a notification for a successful ajax call with failure content', function () { dialog.render(); var response = sinon.stub(); dialog.autocompleteHandler({term: 'bob'}, response); @@ -826,7 +1892,8 @@ describe('OC.Share.ShareDialogView', function() { 'ocs' : { 'meta' : { 'status': 'failure', - 'statuscode': 400 + 'statuscode': 400, + 'message': 'error message' } } }); @@ -835,16 +1902,16 @@ describe('OC.Share.ShareDialogView', function() { {'Content-Type': 'application/json'}, jsonData ); - expect(response.calledWithExactly()).toEqual(true); + expect(response.called).toEqual(false); + expect(showTemporaryNotificationStub.calledOnce).toEqual(true); + expect(showTemporaryNotificationStub.firstCall.args[0]).toContain('error message'); }); it('throws a notification when the ajax search lookup fails', function () { - notificationStub = sinon.stub(OC.Notification, 'show'); dialog.render(); dialog.autocompleteHandler({term: 'bob'}, sinon.stub()); fakeServer.requests[0].respond(500); - expect(notificationStub.calledOnce).toEqual(true); - notificationStub.restore(); + expect(showTemporaryNotificationStub.calledOnce).toEqual(true); }); describe('renders the autocomplete elements', function() { @@ -942,6 +2009,425 @@ describe('OC.Share.ShareDialogView', function() { addShareStub.restore(); }); + + it('hides the loading icon when all the pending operations finish', function() { + dialog.render(); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'bob'}, response); + dialog.autocompleteHandler({term: 'bobby'}, response); + + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } + }); + + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); + + fakeServer.requests[1].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + }); + }); + describe('confirm share', function() { + var addShareStub; + var tooltipStub; + var showTemporaryNotificationStub; + + beforeEach(function() { + addShareStub = sinon.stub(shareModel, 'addShare'); + + tooltipStub = sinon.stub($.fn, 'tooltip').callsFake(function() { + return $('<div></div>'); + }); + + showTemporaryNotificationStub = sinon.stub(OC.Notification, 'showTemporary'); + + dialog.render(); + }); + + afterEach(function() { + addShareStub.restore(); + tooltipStub.restore(); + showTemporaryNotificationStub.restore(); + }); + + it('sets the appropriate UI state while waiting to get the suggestions', function() { + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.callCount).toEqual(1); + expect(typeof autocompleteStub.firstCall.args[0]).toEqual('object'); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); + + dialog.$el.find('.shareWithField').val('bob'); + + dialog._confirmShare(); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); + expect(autocompleteStub.lastCall.args[0]).toEqual('disable'); + expect(autocompleteStub.calledWith('close')).toEqual(true); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true); + expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); + }); + + it('calls addShare with the only suggestion', function() { + dialog.$el.find('.shareWithField').val('bob'); + + dialog._confirmShare(); + + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + } + ], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + // Ensure that the UI is not restored before adding the share + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); + expect(autocompleteStub.lastCall.args[0]).toEqual('disable'); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true); + expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); + + expect(addShareStub.calledOnce).toEqual(true); + expect(addShareStub.firstCall.args[0]).toEqual({ + shareType: OC.Share.SHARE_TYPE_USER, + shareWith: 'user1' + }); + + // "yield" and "callArg" from SinonJS can not be used, as the + // callback is a property not in the first argument. + addShareStub.firstCall.args[1]['success'].apply(shareModel); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); + expect(dialog.$el.find('.shareWithField').val()).toEqual(''); + }); + + it('handles a failure to share', function() { + expect(showTemporaryNotificationStub.called).toEqual(false); + + dialog.$el.find('.shareWithField').val('bob'); + + dialog._confirmShare(); + + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + } + ], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + // Ensure that the UI is not restored before adding the share + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); + expect(autocompleteStub.lastCall.args[0]).toEqual('disable'); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true); + expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); + + expect(addShareStub.calledOnce).toEqual(true); + expect(addShareStub.firstCall.args[0]).toEqual({ + shareType: OC.Share.SHARE_TYPE_USER, + shareWith: 'user1' + }); + + // "yield" and "callArg" from SinonJS can not be used, as the + // callback is a property not in the first argument. + addShareStub.firstCall.args[1]['error'].apply(shareModel); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); + expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); + + expect(showTemporaryNotificationStub.calledOnce).toEqual(true); + }); + + it('restores UI if there are no matches at all', function() { + dialog.$el.find('.shareWithField').val('bob'); + + dialog._confirmShare(); + + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(addShareStub.called).toEqual(false); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); + expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); + + // No explicit tooltip is shown; it is automatically shown when the + // autocomplete is activated again and it finds no matches. + expect(tooltipStub.lastCall.args[0]).not.toEqual('show'); + }); + + it('shows tooltip if there are matches but no exact matches', function() { + dialog.$el.find('.shareWithField').val('bo'); + + dialog._confirmShare(); + + 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' + } + } + ], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(addShareStub.called).toEqual(false); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); + expect(dialog.$el.find('.shareWithField').val()).toEqual('bo'); + }); + + it('shows tooltip if there is more than one exact match', function() { + dialog.$el.find('.shareWithField').val('bob'); + + dialog._confirmShare(); + + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + } + ], + 'groups': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'group1' + } + } + ], + 'remotes': [] + }, + 'users': [], + 'groups': [], + 'remotes': [], + 'lookup': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(addShareStub.called).toEqual(false); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); + expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); + }); + + it('throws a notification for a successful ajax call with failure content', function () { + dialog.$el.find('.shareWithField').val('bob'); + + dialog._confirmShare(); + + var jsonData = JSON.stringify({ + 'ocs' : { + 'meta' : { + 'status': 'failure', + 'statuscode': 400, + 'message': 'error message' + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + + expect(addShareStub.called).toEqual(false); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); + expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); + + expect(showTemporaryNotificationStub.called).toEqual(false); + }); + + it('throws a notification when the ajax search lookup fails', function () { + dialog.$el.find('.shareWithField').val('bob'); + + dialog._confirmShare(); + + fakeServer.requests[0].respond(500); + + expect(addShareStub.called).toEqual(false); + + expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); + expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); + expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); + expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); + + expect(showTemporaryNotificationStub.called).toEqual(false); + }); }); describe('reshare permissions', function() { it('does not show sharing options when sharing not allowed', function() { |