diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index db770ad150..9f47e78582 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -13,7 +13,7 @@ OCA.Sharing = {}; } OCA.Sharing.Util = { - initialize: function() { + initialize: function(fileActions) { if (!_.isUndefined(OC.Share) && !_.isUndefined(OCA.Files)) { // TODO: make a separate class for this or a hook or jQuery event ? if (OCA.Files.FileList) { @@ -28,6 +28,9 @@ tr.attr('data-reshare-permissions', fileData.permissions); } } + if (fileData.recipientsDisplayName) { + tr.attr('data-share-recipients', fileData.recipientsDisplayName); + } return tr; }; } @@ -72,7 +75,7 @@ } }); - OCA.Files.fileActions.register( + fileActions.register( 'all', 'Share', OC.PERMISSION_SHARE, @@ -109,11 +112,7 @@ // is called automatically after this event var userShares = ev.itemShares[OC.Share.SHARE_TYPE_USER] || []; var groupShares = ev.itemShares[OC.Share.SHARE_TYPE_GROUP] || []; - var linkShares = ev.itemShares[OC.Share.SHARE_TYPE_LINK] || []; var recipients = _.union(userShares, groupShares); - if (linkShares.length > 0) { - recipients.unshift(t('files_sharing', 'Public')); - } // only update the recipients if they existed before // (some file lists don't have them) if (!_.isUndefined($tr.attr('data-share-recipients'))) { @@ -131,7 +130,7 @@ }, /** - * Formats a recipient array to be displayed. + * Formats a recipients array to be displayed. * The first four recipients will be shown and the * other ones will be shown as "+x" where "x" is the number of * remaining recipients. @@ -146,7 +145,9 @@ if (!_.isNumber(count)) { count = recipients.length; } - text = _.first(recipients, maxRecipients).join(', '); + // TODO: use natural sort + recipients = _.first(recipients, maxRecipients).sort(); + text = recipients.join(', '); if (count > maxRecipients) { text += ', +' + (count - maxRecipients); } @@ -156,6 +157,9 @@ })(); $(document).ready(function() { - OCA.Sharing.Util.initialize(); + // FIXME: HACK: do not init when running unit tests, need a better way + if (!window.TESTING) { + OCA.Sharing.Util.initialize(OCA.Files.fileActions); + } }); diff --git a/apps/files_sharing/js/sharedfilelist.js b/apps/files_sharing/js/sharedfilelist.js index 9cf74abf67..8a6c3169f9 100644 --- a/apps/files_sharing/js/sharedfilelist.js +++ b/apps/files_sharing/js/sharedfilelist.js @@ -48,9 +48,6 @@ if (this._sharedWithUser) { $tr.attr('data-share-owner', fileData.shares[0].ownerDisplayName); } - if (fileData.recipientsDisplayName) { - $tr.attr('data-share-recipients', fileData.recipientsDisplayName); - } return $tr; }, @@ -201,11 +198,9 @@ data.shares.push(file.share); } - if (file.share.type === OC.Share.SHARE_TYPE_LINK) { - data.hasLinkShare = true; - } else if (recipient) { + if (recipient) { // limit counterparts for output - if (data.recipientsCount < 3) { + if (data.recipientsCount < 4) { // only store the first ones, they will be the only ones // displayed data.recipients[recipient] = true; @@ -222,11 +217,7 @@ .each(function(data) { // convert the recipients map to a flat // array of sorted names - data.recipients = _.chain(data.recipients).keys().sort().value(); - if (data.hasLinkShare) { - data.recipients.unshift(t('files_sharing', 'Public')); - delete data.hasLinkShare; - } + data.recipients = _.keys(data.recipients); data.recipientsDisplayName = OCA.Sharing.Util.formatRecipients( data.recipients, data.recipientsCount diff --git a/apps/files_sharing/tests/js/shareSpec.js b/apps/files_sharing/tests/js/shareSpec.js new file mode 100644 index 0000000000..604a4bb2bb --- /dev/null +++ b/apps/files_sharing/tests/js/shareSpec.js @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2014 Vincent Petry + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +describe('OCA.Sharing.Util tests', function() { + var oldFileListPrototype; + var fileList; + var testFiles; + + beforeEach(function() { + // back up prototype, as it will be extended by + // the sharing code + oldFileListPrototype = _.extend({}, OCA.Files.FileList.prototype); + + var $content = $('
'); + $('#testArea').append($content); + // dummy file list + var $div = $( + '
' + + '' + + '' + + '' + + '
' + + '
'); + $('#content').append($div); + + var fileActions = new OCA.Files.FileActions(); + OCA.Sharing.Util.initialize(fileActions); + fileList = new OCA.Files.FileList( + $div, { + fileActions : fileActions + } + ); + + testFiles = [{ + id: 1, + type: 'file', + name: 'One.txt', + path: '/subdir', + mimetype: 'text/plain', + size: 12, + permissions: 31, + etag: 'abc', + shareOwner: 'User One', + isShareMountPoint: false + }]; + + OCA.Sharing.sharesLoaded = true; + OC.Share.statuses = { + 1: {link: false, path: '/subdir'} + }; + }); + afterEach(function() { + OCA.Files.FileList.prototype = oldFileListPrototype; + delete OCA.Sharing.sharesLoaded; + OC.Share.statuses = {}; + }); + + describe('Sharing data in table row', function() { + // TODO: test data-permissions, data-share-owner, etc + }); + describe('Share action icon', function() { + it('do not shows share text when not shared', function() { + var $action; + OC.Share.statuses = {}; + fileList.setFiles([{ + id: 1, + type: 'file', + name: 'One.txt', + path: '/subdir', + mimetype: 'text/plain', + size: 12, + permissions: 31, + etag: 'abc' + }]); + $action = fileList.$el.find('tbody tr:first .action-share'); + expect($action.hasClass('permanent')).toEqual(false); + expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg'); + }); + it('shows simple share text with share icon', function() { + var $action; + fileList.setFiles([{ + id: 1, + type: 'file', + name: 'One.txt', + path: '/subdir', + mimetype: 'text/plain', + size: 12, + permissions: 31, + etag: 'abc' + }]); + $action = fileList.$el.find('tbody tr:first .action-share'); + expect($action.hasClass('permanent')).toEqual(true); + expect($action.find('>span').text()).toEqual('Shared'); + expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg'); + }); + it('shows simple share text with public icon when shared with link', function() { + var $action; + OC.Share.statuses = {1: {link: true, path: '/subdir'}}; + fileList.setFiles([{ + id: 1, + type: 'file', + name: 'One.txt', + path: '/subdir', + mimetype: 'text/plain', + size: 12, + permissions: 31, + etag: 'abc' + }]); + $action = fileList.$el.find('tbody tr:first .action-share'); + expect($action.hasClass('permanent')).toEqual(true); + expect($action.find('>span').text()).toEqual('Shared'); + expect(OC.basename($action.find('img').attr('src'))).toEqual('public.svg'); + }); + it('shows owner name when owner is available', function() { + var $action; + fileList.setFiles([{ + id: 1, + type: 'file', + name: 'One.txt', + path: '/subdir', + mimetype: 'text/plain', + size: 12, + permissions: 31, + shareOwner: 'User One', + etag: 'abc' + }]); + $action = fileList.$el.find('tbody tr:first .action-share'); + expect($action.hasClass('permanent')).toEqual(true); + expect($action.find('>span').text()).toEqual('Shared by User One'); + expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg'); + }); + it('shows recipients when recipients are available', function() { + var $action; + fileList.setFiles([{ + id: 1, + type: 'file', + name: 'One.txt', + path: '/subdir', + mimetype: 'text/plain', + size: 12, + permissions: 31, + recipientsDisplayName: 'User One, User Two', + etag: 'abc' + }]); + $action = fileList.$el.find('tbody tr:first .action-share'); + expect($action.hasClass('permanent')).toEqual(true); + expect($action.find('>span').text()).toEqual('Shared with User One, User Two'); + expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg'); + }); + }); + describe('Share action', function() { + // TODO: test file action / dropdown trigger + it('updates share icon when shares were changed in dropdown', function() { + fileList.setFiles(testFiles); + fileList.$el.find('tr:first .action-share').click(); + }); + }); + describe('formatRecipients', function() { + it('returns a single recipient when one passed', function() { + expect(OCA.Sharing.Util.formatRecipients(['User one'])) + .toEqual('User one'); + }); + it('returns two recipients when two passed', function() { + expect(OCA.Sharing.Util.formatRecipients(['User one', 'User two'])) + .toEqual('User one, User two'); + }); + it('returns four recipients with plus when five passed', function() { + var recipients = [ + 'User one', + 'User two', + 'User three', + 'User four', + 'User five' + ]; + expect(OCA.Sharing.Util.formatRecipients(recipients)) + .toEqual('User four, User one, User three, User two, +1'); + }); + it('returns four recipients with plus when ten passed', function() { + var recipients = [ + 'User one', + 'User two', + 'User three', + 'User four', + 'User five', + 'User six', + 'User seven', + 'User eight', + 'User nine', + 'User ten' + ]; + expect(OCA.Sharing.Util.formatRecipients(recipients)) + .toEqual('User four, User one, User three, User two, +6'); + }); + it('returns four recipients with plus when four passed with counter', function() { + var recipients = [ + 'User one', + 'User two', + 'User three', + 'User four' + ]; + expect(OCA.Sharing.Util.formatRecipients(recipients, 10)) + .toEqual('User four, User one, User three, User two, +6'); + }); + }); + +}); diff --git a/core/js/share.js b/core/js/share.js index d802053176..c4ca63908a 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -48,7 +48,7 @@ OC.Share={ currentDir = fileList.getCurrentDirectory(); } for (item in OC.Share.statuses){ - var image = OC.imagePath('core', 'actions/shared'); + var image = OC.imagePath('core', 'actions/share'); var data = OC.Share.statuses[item]; var hasLink = data.link; // Links override shared in terms of icon display @@ -113,7 +113,7 @@ OC.Share={ } } else if (OC.Share.itemShares[index].length > 0) { shares = true; - image = OC.imagePath('core', 'actions/shared'); + image = OC.imagePath('core', 'actions/share'); } } }); @@ -165,17 +165,7 @@ OC.Share={ image = image || OC.imagePath('core', 'actions/share'); } if (recipients) { - image = image || OC.imagePath('core', 'actions/shared'); - if (owner) { - message = ' ' + t( - 'files_sharing', - 'Shared by {owner} with You, {recipients}', - {owner: owner, recipients: recipients} - ); - } - else { - message = t('core', 'Shared with {recipients}', {recipients: recipients}); - } + message = t('core', 'Shared with {recipients}', {recipients: recipients}); } action.html(' '+ message + '').prepend(img); } diff --git a/tests/karma.config.js b/tests/karma.config.js index 846e8f7be9..1f903f5821 100644 --- a/tests/karma.config.js +++ b/tests/karma.config.js @@ -52,7 +52,8 @@ module.exports = function(config) { // only test these files, others are not ready and mess // up with the global namespace/classes/state 'apps/files_sharing/js/app.js', - 'apps/files_sharing/js/sharedfilelist.js' + 'apps/files_sharing/js/sharedfilelist.js', + 'apps/files_sharing/js/share.js' ], testFiles: ['apps/files_sharing/tests/js/*.js'] }];