aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2018-03-21 15:08:39 +0100
committerGitHub <noreply@github.com>2018-03-21 15:08:39 +0100
commit6f455d5c4153130b0a368938a408aa2369fa66c0 (patch)
tree91f107ae691804e0bc9a1ce83e0f39346b968b7f /core
parent24292be917ec99e273b3e39b2a4f99292935e331 (diff)
parent203bf51543f7d1866efeaa9decd2817cb41b3c3e (diff)
downloadnextcloud-server-6f455d5c4153130b0a368938a408aa2369fa66c0.tar.gz
nextcloud-server-6f455d5c4153130b0a368938a408aa2369fa66c0.zip
Merge pull request #7196 from nextcloud/sharing-confirm-button
Add confirmation button to share input
Diffstat (limited to 'core')
-rw-r--r--core/js/sharedialogview.js560
-rw-r--r--core/js/tests/specs/sharedialogviewSpec.js1570
2 files changed, 1900 insertions, 230 deletions
diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js
index d2c63490141..dede768fad5 100644
--- a/core/js/sharedialogview.js
+++ b/core/js/sharedialogview.js
@@ -22,7 +22,7 @@
'<div class="oneline">' +
' <input id="shareWith-{{cid}}" class="shareWithField" type="text" placeholder="{{sharePlaceholder}}" />' +
' <span class="shareWithLoading icon-loading-small hidden"></span>'+
- '{{{shareInfo}}}' +
+ ' <span class="shareWithConfirm icon icon-confirm"></span>' +
'</div>' +
'{{/if}}' +
'<div class="shareeListView subView"></div>' +
@@ -30,10 +30,6 @@
'<div class="expirationView subView"></div>' +
'<div class="loading hidden" style="height: 50px"></div>';
- var TEMPLATE_SHARE_INFO =
- '<span class="icon icon-info shareWithRemoteInfo hasTooltip" ' +
- 'title="{{tooltip}}"></span>';
-
/**
* @class OCA.Share.ShareDialogView
* @member {OC.Share.ShareItemModel} model
@@ -69,9 +65,16 @@
/** @type {object} **/
shareeListView: undefined,
+ /** @type {object} **/
+ _lastSuggestions: undefined,
+
+ /** @type {int} **/
+ _pendingOperationsCount: 0,
+
events: {
'focus .shareWithField': 'onShareWithFieldFocus',
- 'input .shareWithField': 'onShareWithFieldChanged'
+ 'input .shareWithField': 'onShareWithFieldChanged',
+ 'click .shareWithConfirm': '_confirmShare'
},
initialize: function(options) {
@@ -138,11 +141,182 @@
this.$el.find('.shareWithField').autocomplete("search");
},
+ _getSuggestions: function(searchTerm, perPage, model) {
+ if (this._lastSuggestions &&
+ this._lastSuggestions.searchTerm === searchTerm &&
+ this._lastSuggestions.perPage === perPage &&
+ this._lastSuggestions.model === model) {
+ return this._lastSuggestions.promise;
+ }
+
+ var deferred = $.Deferred();
+
+ $.get(
+ OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees',
+ {
+ format: 'json',
+ search: searchTerm,
+ perPage: perPage,
+ itemType: model.get('itemType')
+ },
+ function (result) {
+ if (result.ocs.meta.statuscode === 100) {
+ var filter = function(users, groups, remotes, emails, circles) {
+ if (typeof(emails) === 'undefined') {
+ emails = [];
+ }
+ if (typeof(circles) === 'undefined') {
+ circles = [];
+ }
+
+ var usersLength;
+ var groupsLength;
+ var remotesLength;
+ var emailsLength;
+ var circlesLength;
+
+ 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
+ if (model.hasReshare()) {
+ usersLength = users.length;
+ for (i = 0 ; i < usersLength; i++) {
+ if (users[i].value.shareWith === model.getReshareOwner()) {
+ users.splice(i, 1);
+ break;
+ }
+ }
+ }
+
+ var shares = 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;
+ }
+ }
+ } else if (share.share_type === OC.Share.SHARE_TYPE_EMAIL) {
+ emailsLength = emails.length;
+ for (j = 0; j < emailsLength; j++) {
+ if (emails[j].value.shareWith === share.share_with) {
+ emails.splice(j, 1);
+ break;
+ }
+ }
+ } else if (share.share_type === OC.Share.SHARE_TYPE_CIRCLE) {
+ circlesLength = circles.length;
+ for (j = 0; j < circlesLength; j++) {
+ if (circles[j].value.shareWith === share.share_with) {
+ circles.splice(j, 1);
+ break;
+ }
+ }
+ }
+ }
+ };
+
+ filter(
+ result.ocs.data.exact.users,
+ result.ocs.data.exact.groups,
+ result.ocs.data.exact.remotes,
+ result.ocs.data.exact.emails,
+ result.ocs.data.exact.circles
+ );
+
+ var exactUsers = result.ocs.data.exact.users;
+ var exactGroups = result.ocs.data.exact.groups;
+ var exactRemotes = result.ocs.data.exact.remotes;
+ var exactEmails = [];
+ if (typeof(result.ocs.data.emails) !== 'undefined') {
+ exactEmails = result.ocs.data.exact.emails;
+ }
+ var exactCircles = [];
+ if (typeof(result.ocs.data.circles) !== 'undefined') {
+ exactCircles = result.ocs.data.exact.circles;
+ }
+
+ var exactMatches = exactUsers.concat(exactGroups).concat(exactRemotes).concat(exactEmails).concat(exactCircles);
+
+ filter(
+ result.ocs.data.users,
+ result.ocs.data.groups,
+ result.ocs.data.remotes,
+ result.ocs.data.emails,
+ result.ocs.data.circles
+ );
+
+ var users = result.ocs.data.users;
+ var groups = result.ocs.data.groups;
+ var remotes = result.ocs.data.remotes;
+ var lookup = result.ocs.data.lookup;
+ var emails = [];
+ if (typeof(result.ocs.data.emails) !== 'undefined') {
+ emails = result.ocs.data.emails;
+ }
+ var circles = [];
+ if (typeof(result.ocs.data.circles) !== 'undefined') {
+ circles = result.ocs.data.circles;
+ }
+
+ var suggestions = exactMatches.concat(users).concat(groups).concat(remotes).concat(emails).concat(circles).concat(lookup);
+
+ deferred.resolve(suggestions, exactMatches);
+ } else {
+ deferred.reject(result.ocs.meta.message);
+ }
+ }
+ ).fail(function() {
+ deferred.reject();
+ });
+
+ this._lastSuggestions = {
+ searchTerm: searchTerm,
+ perPage: perPage,
+ model: model,
+ promise: deferred.promise()
+ };
+
+ return this._lastSuggestions.promise;
+ },
+
autocompleteHandler: function (search, response) {
var $shareWithField = $('.shareWithField'),
view = this,
$loading = this.$el.find('.shareWithLoading'),
- $shareInfo = this.$el.find('.shareWithRemoteInfo');
+ $confirm = this.$el.find('.shareWithConfirm');
var count = oc_config['sharing.minSearchStringLength'];
if (search.term.trim().length < count) {
@@ -167,160 +341,70 @@
$loading.removeClass('hidden');
$loading.addClass('inlineblock');
- $shareInfo.addClass('hidden');
+ $confirm.addClass('hidden');
+ this._pendingOperationsCount++;
$shareWithField.removeClass('error')
.tooltip('hide');
var perPage = 200;
- $.get(
- OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees',
- {
- format: 'json',
- search: search.term.trim(),
- perPage: perPage,
- itemType: view.model.get('itemType')
- },
- function (result) {
+ this._getSuggestions(
+ search.term.trim(),
+ perPage,
+ view.model
+ ).done(function(suggestions) {
+ view._pendingOperationsCount--;
+ if (view._pendingOperationsCount === 0) {
$loading.addClass('hidden');
$loading.removeClass('inlineblock');
- $shareInfo.removeClass('hidden');
- if (result.ocs.meta.statuscode === 100) {
- 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);
- var lookup = result.ocs.data.lookup;
- var emails = [],
- circles = [];
- if (typeof(result.ocs.data.emails) !== 'undefined') {
- emails = result.ocs.data.exact.emails.concat(result.ocs.data.emails);
- }
- if (typeof(result.ocs.data.circles) !== 'undefined') {
- circles = result.ocs.data.exact.circles.concat(result.ocs.data.circles);
- }
-
- var usersLength;
- var groupsLength;
- var remotesLength;
- var emailsLength;
- var circlesLength;
-
- 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
- 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;
-
- // 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;
- }
- }
- } else if (share.share_type === OC.Share.SHARE_TYPE_EMAIL) {
- emailsLength = emails.length;
- for (j = 0; j < emailsLength; j++) {
- if (emails[j].value.shareWith === share.share_with) {
- emails.splice(j, 1);
- break;
- }
- }
- } else if (share.share_type === OC.Share.SHARE_TYPE_CIRCLE) {
- circlesLength = circles.length;
- for (j = 0; j < circlesLength; j++) {
- if (circles[j].value.shareWith === share.share_with) {
- circles.splice(j, 1);
- break;
- }
- }
- }
- }
-
- var suggestions = users.concat(groups).concat(remotes).concat(emails).concat(circles).concat(lookup);
+ $confirm.removeClass('hidden');
+ }
- if (suggestions.length > 0) {
- $shareWithField
- .autocomplete("option", "autoFocus", true);
+ if (suggestions.length > 0) {
+ $shareWithField
+ .autocomplete("option", "autoFocus", true);
- response(suggestions);
+ response(suggestions);
- // show a notice that the list is truncated
- // this is the case if one of the search results is at least as long as the max result config option
- if(oc_config['sharing.maxAutocompleteResults'] > 0 &&
- Math.min(perPage, oc_config['sharing.maxAutocompleteResults'])
- <= Math.max(users.length, groups.length, remotes.length, emails.length, lookup.length)) {
+ // show a notice that the list is truncated
+ // this is the case if one of the search results is at least as long as the max result config option
+ if(oc_config['sharing.maxAutocompleteResults'] > 0 &&
+ Math.min(perPage, oc_config['sharing.maxAutocompleteResults'])
+ <= Math.max(users.length, groups.length, remotes.length, emails.length, lookup.length)) {
- var message = t('core', 'This list is maybe truncated - please refine your search term to see more results.');
- $('.ui-autocomplete').append('<li class="autocomplete-note">' + message + '</li>');
- }
+ var message = t('core', 'This list is maybe truncated - please refine your search term to see more results.');
+ $('.ui-autocomplete').append('<li class="autocomplete-note">' + message + '</li>');
+ }
- } else {
- var title = t('core', 'No users or groups found for {search}', {search: $shareWithField.val()});
- if (!view.configModel.get('allowGroupSharing')) {
- title = t('core', 'No users found for {search}', {search: $('.shareWithField').val()});
- }
- $shareWithField.addClass('error')
- .attr('data-original-title', title)
- .tooltip('hide')
- .tooltip({
- placement: 'bottom',
- trigger: 'manual'
- })
- .tooltip('fixTitle')
- .tooltip('show');
- response();
- }
- } else {
- response();
+ } else {
+ var title = t('core', 'No users or groups found for {search}', {search: $shareWithField.val()});
+ if (!view.configModel.get('allowGroupSharing')) {
+ title = t('core', 'No users found for {search}', {search: $('.shareWithField').val()});
}
+ $shareWithField.addClass('error')
+ .attr('data-original-title', title)
+ .tooltip('hide')
+ .tooltip({
+ placement: 'bottom',
+ trigger: 'manual'
+ })
+ .tooltip('fixTitle')
+ .tooltip('show');
+ response();
+ }
+ }).fail(function(message) {
+ view._pendingOperationsCount--;
+ if (view._pendingOperationsCount === 0) {
+ $loading.addClass('hidden');
+ $loading.removeClass('inlineblock');
+ $confirm.removeClass('hidden');
+ }
+
+ if (message) {
+ OC.Notification.showTemporary(t('core', 'An error occurred ("{message}"). Please try again', { message: message }));
+ } else {
+ OC.Notification.showTemporary(t('core', 'An error occurred. Please try again'));
}
- ).fail(function() {
- $loading.addClass('hidden');
- $loading.removeClass('inlineblock');
- $shareInfo.removeClass('hidden');
- OC.Notification.show(t('core', 'An error occurred. Please try again'));
- window.setTimeout(OC.Notification.hide, 5000);
});
},
@@ -357,31 +441,149 @@
},
_onSelectRecipient: function(e, s) {
+ var self = this;
+
e.preventDefault();
+ // Ensure that the keydown handler for the input field is not
+ // called; otherwise it would try to add the recipient again, which
+ // would fail.
+ e.stopImmediatePropagation();
$(e.target).attr('disabled', true)
.val(s.item.label);
+
var $loading = this.$el.find('.shareWithLoading');
- $loading.removeClass('hidden')
- .addClass('inlineblock');
- var $shareInfo = this.$el.find('.shareWithRemoteInfo');
- $shareInfo.addClass('hidden');
+ var $confirm = this.$el.find('.shareWithConfirm');
+
+ $loading.removeClass('hidden');
+ $loading.addClass('inlineblock');
+ $confirm.addClass('hidden');
+ this._pendingOperationsCount++;
this.model.addShare(s.item.value, {success: function() {
+ // Adding a share changes the suggestions.
+ self._lastSuggestions = undefined;
+
$(e.target).val('')
.attr('disabled', false);
- $loading.addClass('hidden')
- .removeClass('inlineblock');
- $shareInfo.removeClass('hidden');
+
+ self._pendingOperationsCount--;
+ if (self._pendingOperationsCount === 0) {
+ $loading.addClass('hidden');
+ $loading.removeClass('inlineblock');
+ $confirm.removeClass('hidden');
+ }
}, error: function(obj, msg) {
OC.Notification.showTemporary(msg);
$(e.target).attr('disabled', false)
.autocomplete('search', $(e.target).val());
- $loading.addClass('hidden')
- .removeClass('inlineblock');
- $shareInfo.removeClass('hidden');
+
+ self._pendingOperationsCount--;
+ if (self._pendingOperationsCount === 0) {
+ $loading.addClass('hidden');
+ $loading.removeClass('inlineblock');
+ $confirm.removeClass('hidden');
+ }
}});
},
+ _confirmShare: function() {
+ var self = this;
+ var $shareWithField = $('.shareWithField');
+ var $loading = this.$el.find('.shareWithLoading');
+ var $confirm = this.$el.find('.shareWithConfirm');
+
+ $loading.removeClass('hidden');
+ $loading.addClass('inlineblock');
+ $confirm.addClass('hidden');
+ this._pendingOperationsCount++;
+
+ $shareWithField.prop('disabled', true);
+
+ // Disabling the autocompletion does not clear its search timeout;
+ // removing the focus from the input field does, but only if the
+ // autocompletion is not disabled when the field loses the focus.
+ // Thus, the field has to be disabled before disabling the
+ // autocompletion to prevent an old pending search result from
+ // appearing once the field is enabled again.
+ $shareWithField.autocomplete('close');
+ $shareWithField.autocomplete('disable');
+
+ var restoreUI = function() {
+ self._pendingOperationsCount--;
+ if (self._pendingOperationsCount === 0) {
+ $loading.addClass('hidden');
+ $loading.removeClass('inlineblock');
+ $confirm.removeClass('hidden');
+ }
+
+ $shareWithField.prop('disabled', false);
+ $shareWithField.focus();
+ };
+
+ var perPage = 200;
+ var onlyExactMatches = true;
+ this._getSuggestions(
+ $shareWithField.val(),
+ perPage,
+ this.model,
+ onlyExactMatches
+ ).done(function(suggestions, exactMatches) {
+ if (suggestions.length === 0) {
+ restoreUI();
+
+ $shareWithField.autocomplete('enable');
+
+ // There is no need to show an error message here; it will
+ // be automatically shown when the autocomplete is activated
+ // again (due to the focus on the field) and it finds no
+ // matches.
+
+ return;
+ }
+
+ if (exactMatches.length !== 1) {
+ restoreUI();
+
+ $shareWithField.autocomplete('enable');
+
+ return;
+ }
+
+ var actionSuccess = function() {
+ // Adding a share changes the suggestions.
+ self._lastSuggestions = undefined;
+
+ $shareWithField.val('');
+
+ restoreUI();
+
+ $shareWithField.autocomplete('enable');
+ };
+
+ var actionError = function(obj, msg) {
+ restoreUI();
+
+ $shareWithField.autocomplete('enable');
+
+ OC.Notification.showTemporary(msg);
+ };
+
+ self.model.addShare(exactMatches[0].value, {
+ success: actionSuccess,
+ error: actionError
+ });
+ }).fail(function(message) {
+ restoreUI();
+
+ $shareWithField.autocomplete('enable');
+
+ // There is no need to show an error message here; it will be
+ // automatically shown when the autocomplete is activated again
+ // (due to the focus on the field) and getting the suggestions
+ // fail.
+ });
+ },
+
_toggleLoading: function(state) {
this._loading = state;
this.$el.find('.subView').toggleClass('hidden', state);
@@ -410,18 +612,28 @@
},
render: function() {
+ var self = this;
var baseTemplate = this._getTemplate('base', TEMPLATE_BASE);
this.$el.html(baseTemplate({
cid: this.cid,
shareLabel: t('core', 'Share'),
sharePlaceholder: this._renderSharePlaceholderPart(),
- shareInfo: this._renderShareInfoPart(),
isSharingAllowed: this.model.sharePermissionPossible()
}));
var $shareField = this.$el.find('.shareWithField');
if ($shareField.length) {
+ var shareFieldKeydownHandler = function(event) {
+ if (event.keyCode !== 13) {
+ return true;
+ }
+
+ self._confirmShare();
+
+ return false;
+ };
+
$shareField.autocomplete({
minLength: 1,
delay: 750,
@@ -431,6 +643,8 @@
source: this.autocompleteHandler,
select: this._onSelectRecipient
}).data('ui-autocomplete')._renderItem = this.autocompleteRenderItem;
+
+ $shareField.on('keydown', null, shareFieldKeydownHandler);
}
this.resharerInfoView.$el = this.$el.find('.resharerInfoView');
@@ -461,27 +675,6 @@
this.linkShareView.showLink = this._showLink;
},
- _renderShareInfoPart: function() {
- var shareInfo = '';
- var infoTemplate = this._getShareInfoTemplate();
-
- if(this.configModel.get('isMailShareAllowed') && this.configModel.get('isRemoteShareAllowed')) {
- shareInfo = infoTemplate({
- tooltip: t('core', 'Share with other people by entering a user or group, a federated cloud ID or an email address.')
- });
- } else if(this.configModel.get('isRemoteShareAllowed')) {
- shareInfo = infoTemplate({
- tooltip: t('core', 'Share with other people by entering a user or group or a federated cloud ID.')
- });
- } else if(this.configModel.get('isMailShareAllowed')) {
- shareInfo = infoTemplate({
- tooltip: t('core', 'Share with other people by entering a user or group or an email address.')
- });
- }
-
- return shareInfo;
- },
-
_renderSharePlaceholderPart: function () {
var allowRemoteSharing = this.configModel.get('isRemoteShareAllowed');
var allowMailSharing = this.configModel.get('isMailShareAllowed');
@@ -513,15 +706,6 @@
return this._templates[key];
},
- /**
- * returns the info template for remote sharing
- *
- * @returns {Function}
- * @private
- */
- _getShareInfoTemplate: function() {
- return this._getTemplate('shareInfo', TEMPLATE_SHARE_INFO);
- }
});
OC.Share.ShareDialogView = ShareDialogView;
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() {