Fix sharing breadcrumbs
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
This commit is contained in:
parent
eebcf89091
commit
5d2c89ca6c
15 changed files with 161 additions and 5645 deletions
BIN
apps/files_sharing/js/dist/additionalScripts.js
vendored
BIN
apps/files_sharing/js/dist/additionalScripts.js
vendored
Binary file not shown.
BIN
apps/files_sharing/js/dist/additionalScripts.js.map
vendored
BIN
apps/files_sharing/js/dist/additionalScripts.js.map
vendored
Binary file not shown.
BIN
apps/files_sharing/js/dist/files_sharing.4.js
vendored
BIN
apps/files_sharing/js/dist/files_sharing.4.js
vendored
Binary file not shown.
BIN
apps/files_sharing/js/dist/files_sharing.4.js.map
vendored
BIN
apps/files_sharing/js/dist/files_sharing.4.js.map
vendored
Binary file not shown.
BIN
apps/files_sharing/js/dist/files_sharing.5.js
vendored
BIN
apps/files_sharing/js/dist/files_sharing.5.js
vendored
Binary file not shown.
BIN
apps/files_sharing/js/dist/files_sharing.5.js.map
vendored
BIN
apps/files_sharing/js/dist/files_sharing.5.js.map
vendored
Binary file not shown.
|
@ -20,10 +20,31 @@
|
|||
if (!OCA.Sharing) {
|
||||
OCA.Sharing = {}
|
||||
}
|
||||
|
||||
OC.Share = _.extend(OC.Share || {}, {
|
||||
SHARE_TYPE_USER: 0,
|
||||
SHARE_TYPE_GROUP: 1,
|
||||
SHARE_TYPE_LINK: 3,
|
||||
SHARE_TYPE_EMAIL: 4,
|
||||
SHARE_TYPE_REMOTE: 6,
|
||||
SHARE_TYPE_CIRCLE: 7,
|
||||
SHARE_TYPE_GUEST: 8,
|
||||
SHARE_TYPE_REMOTE_GROUP: 9,
|
||||
SHARE_TYPE_ROOM: 10
|
||||
})
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
OCA.Sharing.Util = {
|
||||
|
||||
/**
|
||||
* Regular expression for splitting parts of remote share owners:
|
||||
* "user@example.com/path/to/owncloud"
|
||||
* "user@anotherexample.com@example.com/path/to/owncloud
|
||||
*/
|
||||
_REMOTE_OWNER_REGEXP: new RegExp('^([^@]*)@(([^@]*)@)?([^/]*)([/](.*)?)?$'),
|
||||
|
||||
/**
|
||||
* Initialize the sharing plugin.
|
||||
*
|
||||
|
@ -210,9 +231,7 @@
|
|||
})
|
||||
|
||||
// register share breadcrumbs component
|
||||
var shareTab = new OCA.Sharing.ShareTabView('sharing', {order: -20})
|
||||
|
||||
var breadCrumbSharingDetailView = new OCA.Sharing.ShareBreadCrumbView({ shareTab: shareTab })
|
||||
var breadCrumbSharingDetailView = new OCA.Sharing.ShareBreadCrumbView()
|
||||
fileList.registerBreadCrumbDetailView(breadCrumbSharingDetailView)
|
||||
},
|
||||
|
||||
|
@ -313,9 +332,9 @@
|
|||
// even if reshared, only show "Shared by"
|
||||
if (ownerId) {
|
||||
message = t('core', 'Shared by')
|
||||
avatars = this._formatRemoteShare(ownerId, owner, message)
|
||||
avatars = OCA.Sharing.Util._formatRemoteShare(ownerId, owner, message)
|
||||
} else if (recipients) {
|
||||
avatars = this._formatShareList(recipients)
|
||||
avatars = OCA.Sharing.Util._formatShareList(recipients)
|
||||
}
|
||||
action.html(avatars).prepend(icon)
|
||||
|
||||
|
@ -334,6 +353,140 @@
|
|||
}
|
||||
icon.removeClass('icon-shared icon-public').addClass(iconClass)
|
||||
},
|
||||
/**
|
||||
* Format a remote address
|
||||
*
|
||||
* @param {String} shareWith userid, full remote share, or whatever
|
||||
* @param {String} shareWithDisplayName
|
||||
* @param {String} message
|
||||
* @returns {String} HTML code to display
|
||||
*/
|
||||
_formatRemoteShare: function(shareWith, shareWithDisplayName, message) {
|
||||
var parts = OCA.Sharing.Util._REMOTE_OWNER_REGEXP.exec(shareWith)
|
||||
if (!parts) {
|
||||
// display avatar of the user
|
||||
var avatar = '<span class="avatar" data-username="' + escapeHTML(shareWith) + '" title="' + message + ' ' + escapeHTML(shareWithDisplayName) + '"></span>'
|
||||
var hidden = '<span class="hidden-visually">' + message + ' ' + escapeHTML(shareWithDisplayName) + '</span> '
|
||||
return avatar + hidden
|
||||
}
|
||||
|
||||
var userName = parts[1]
|
||||
var userDomain = parts[3]
|
||||
var server = parts[4]
|
||||
var tooltip = message + ' ' + userName
|
||||
if (userDomain) {
|
||||
tooltip += '@' + userDomain
|
||||
}
|
||||
if (server) {
|
||||
if (!userDomain) {
|
||||
userDomain = '…'
|
||||
}
|
||||
tooltip += '@' + server
|
||||
}
|
||||
|
||||
var html = '<span class="remoteAddress" title="' + escapeHTML(tooltip) + '">'
|
||||
html += '<span class="username">' + escapeHTML(userName) + '</span>'
|
||||
if (userDomain) {
|
||||
html += '<span class="userDomain">@' + escapeHTML(userDomain) + '</span>'
|
||||
}
|
||||
html += '</span> '
|
||||
return html
|
||||
},
|
||||
/**
|
||||
* Loop over all recipients in the list and format them using
|
||||
* all kind of fancy magic.
|
||||
*
|
||||
* @param {Object} recipients array of all the recipients
|
||||
* @returns {String[]} modified list of recipients
|
||||
*/
|
||||
_formatShareList: function(recipients) {
|
||||
var _parent = this
|
||||
recipients = _.toArray(recipients)
|
||||
recipients.sort(function(a, b) {
|
||||
return a.shareWithDisplayName.localeCompare(b.shareWithDisplayName)
|
||||
})
|
||||
return $.map(recipients, function(recipient) {
|
||||
return _parent._formatRemoteShare(recipient.shareWith, recipient.shareWithDisplayName, t('core', 'Shared with'))
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Marks/unmarks a given file as shared by changing its action icon
|
||||
* and folder icon.
|
||||
*
|
||||
* @param $tr file element to mark as shared
|
||||
* @param hasShares whether shares are available
|
||||
* @param hasLink whether link share is available
|
||||
*/
|
||||
markFileAsShared: function($tr, hasShares, hasLink) {
|
||||
var action = $tr.find('.fileactions .action[data-action="Share"]')
|
||||
var type = $tr.data('type')
|
||||
var icon = action.find('.icon')
|
||||
var message, recipients, avatars
|
||||
var ownerId = $tr.attr('data-share-owner-id')
|
||||
var owner = $tr.attr('data-share-owner')
|
||||
var mountType = $tr.attr('data-mounttype')
|
||||
var shareFolderIcon
|
||||
var iconClass = 'icon-shared'
|
||||
action.removeClass('shared-style')
|
||||
// update folder icon
|
||||
if (type === 'dir' && (hasShares || hasLink || ownerId)) {
|
||||
if (typeof mountType !== 'undefined' && mountType !== 'shared-root' && mountType !== 'shared') {
|
||||
shareFolderIcon = OC.MimeType.getIconUrl('dir-' + mountType)
|
||||
} else if (hasLink) {
|
||||
shareFolderIcon = OC.MimeType.getIconUrl('dir-public')
|
||||
} else {
|
||||
shareFolderIcon = OC.MimeType.getIconUrl('dir-shared')
|
||||
}
|
||||
$tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')')
|
||||
$tr.attr('data-icon', shareFolderIcon)
|
||||
} else if (type === 'dir') {
|
||||
var isEncrypted = $tr.attr('data-e2eencrypted')
|
||||
// FIXME: duplicate of FileList._createRow logic for external folder,
|
||||
// need to refactor the icon logic into a single code path eventually
|
||||
if (isEncrypted === 'true') {
|
||||
shareFolderIcon = OC.MimeType.getIconUrl('dir-encrypted')
|
||||
$tr.attr('data-icon', shareFolderIcon)
|
||||
} else if (mountType && mountType.indexOf('external') === 0) {
|
||||
shareFolderIcon = OC.MimeType.getIconUrl('dir-external')
|
||||
$tr.attr('data-icon', shareFolderIcon)
|
||||
} else {
|
||||
shareFolderIcon = OC.MimeType.getIconUrl('dir')
|
||||
// back to default
|
||||
$tr.removeAttr('data-icon')
|
||||
}
|
||||
$tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')')
|
||||
}
|
||||
// update share action text / icon
|
||||
if (hasShares || ownerId) {
|
||||
recipients = $tr.data('share-recipient-data')
|
||||
action.addClass('shared-style')
|
||||
|
||||
avatars = '<span>' + t('core', 'Shared') + '</span>'
|
||||
// even if reshared, only show "Shared by"
|
||||
if (ownerId) {
|
||||
message = t('core', 'Shared by')
|
||||
avatars = this._formatRemoteShare(ownerId, owner, message)
|
||||
} else if (recipients) {
|
||||
avatars = this._formatShareList(recipients)
|
||||
}
|
||||
action.html(avatars).prepend(icon)
|
||||
|
||||
if (ownerId || recipients) {
|
||||
var avatarElement = action.find('.avatar')
|
||||
avatarElement.each(function() {
|
||||
$(this).avatar($(this).data('username'), 32)
|
||||
})
|
||||
action.find('span[title]').tooltip({ placement: 'top' })
|
||||
}
|
||||
} else {
|
||||
action.html('<span class="hidden-visually">' + t('core', 'Shared') + '</span>').prepend(icon)
|
||||
}
|
||||
if (hasLink) {
|
||||
iconClass = 'icon-public'
|
||||
}
|
||||
icon.removeClass('icon-shared icon-public').addClass(iconClass)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Array} fileData
|
||||
|
|
|
@ -30,13 +30,6 @@
|
|||
},
|
||||
_dirInfo: undefined,
|
||||
|
||||
/** @type OCA.Sharing.ShareTabView */
|
||||
_shareTab: undefined,
|
||||
|
||||
initialize: function(options) {
|
||||
this._shareTab = options.shareTab
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
this._dirInfo = data.dirInfo || null
|
||||
|
||||
|
@ -72,28 +65,10 @@
|
|||
dirInfo: self._dirInfo
|
||||
})
|
||||
})
|
||||
this._shareTab.on('sharesChanged', function(shareModel) {
|
||||
var shareTypes = []
|
||||
var shares = shareModel.getSharesWithCurrentItem()
|
||||
|
||||
for (var i = 0; i < shares.length; i++) {
|
||||
if (shareTypes.indexOf(shares[i].share_type) === -1) {
|
||||
shareTypes.push(shares[i].share_type)
|
||||
}
|
||||
}
|
||||
|
||||
if (shareModel.hasLinkShares()) {
|
||||
shareTypes.push(OC.Share.SHARE_TYPE_LINK)
|
||||
}
|
||||
|
||||
// Since the dirInfo isn't updated we need to do this dark hackery
|
||||
self._dirInfo.shareTypes = shareTypes
|
||||
|
||||
self.render({
|
||||
dirInfo: self._dirInfo
|
||||
})
|
||||
})
|
||||
OCA.Files.App.fileList.showDetailsView(fileInfoModel, 'sharing')
|
||||
var path = fileInfoModel.attributes.path + '/' + fileInfoModel.attributes.name
|
||||
OCA.Files.Sidebar.file = path
|
||||
OCA.Files.Sidebar.activeTab = 'sharing'
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -1,240 +0,0 @@
|
|||
/**
|
||||
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('OCA.Sharing.ShareBreadCrumbView tests', function() {
|
||||
var BreadCrumb = OCA.Files.BreadCrumb;
|
||||
var SharedBreadCrum = OCA.Sharing.ShareBreadCrumbView;
|
||||
|
||||
describe('Rendering', function() {
|
||||
var bc;
|
||||
var sbc;
|
||||
var shareTab;
|
||||
beforeEach(function() {
|
||||
bc = new BreadCrumb({
|
||||
getCrumbUrl: function(part, index) {
|
||||
// for testing purposes
|
||||
return part.dir + '#' + index;
|
||||
}
|
||||
});
|
||||
shareTab = new OCA.Sharing.ShareTabView();
|
||||
sbc = new SharedBreadCrum({
|
||||
shareTab: shareTab
|
||||
});
|
||||
bc.addDetailView(sbc);
|
||||
});
|
||||
afterEach(function() {
|
||||
bc = null;
|
||||
sbc = null;
|
||||
shareModel = null;
|
||||
});
|
||||
it('Do not render in root', function() {
|
||||
var dirInfo = new OC.Files.FileInfo({
|
||||
id: 42,
|
||||
path: '/',
|
||||
type: 'dir',
|
||||
name: ''
|
||||
});
|
||||
bc.setDirectoryInfo(dirInfo);
|
||||
bc.setDirectory('');
|
||||
bc.render();
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
expect(bc.$el.find('.icon-shared').length).toEqual(0);
|
||||
expect(bc.$el.find('.shared').length).toEqual(0);
|
||||
expect(bc.$el.find('.icon-public').length).toEqual(0);
|
||||
});
|
||||
it('Render in dir', function() {
|
||||
var dirInfo = new OC.Files.FileInfo({
|
||||
id: 42,
|
||||
path: '/foo',
|
||||
type: 'dir'
|
||||
});
|
||||
bc.setDirectoryInfo(dirInfo);
|
||||
bc.setDirectory('/foo');
|
||||
bc.render();
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
expect(bc.$el.find('.icon-shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.shared').length).toEqual(0);
|
||||
expect(bc.$el.find('.icon-public').length).toEqual(0);
|
||||
});
|
||||
it('Render shared if dir is shared with user', function() {
|
||||
var dirInfo = new OC.Files.FileInfo({
|
||||
id: 42,
|
||||
path: '/foo',
|
||||
type: 'dir',
|
||||
shareTypes: [OC.Share.SHARE_TYPE_USER]
|
||||
});
|
||||
bc.setDirectoryInfo(dirInfo);
|
||||
bc.setDirectory('/foo');
|
||||
bc.render();
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
expect(bc.$el.find('.icon-shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.icon-public').length).toEqual(0);
|
||||
});
|
||||
it('Render shared if dir is shared with group', function() {
|
||||
var dirInfo = new OC.Files.FileInfo({
|
||||
id: 42,
|
||||
path: '/foo',
|
||||
type: 'dir',
|
||||
shareTypes: [OC.Share.SHARE_TYPE_GROUP]
|
||||
});
|
||||
bc.setDirectoryInfo(dirInfo);
|
||||
bc.setDirectory('/foo');
|
||||
bc.render();
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
expect(bc.$el.find('.icon-shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.icon-public').length).toEqual(0);
|
||||
});
|
||||
it('Render shared if dir is shared by link', function() {
|
||||
var dirInfo = new OC.Files.FileInfo({
|
||||
id: 42,
|
||||
path: '/foo',
|
||||
type: 'dir',
|
||||
shareTypes: [OC.Share.SHARE_TYPE_LINK]
|
||||
});
|
||||
bc.setDirectoryInfo(dirInfo);
|
||||
bc.setDirectory('/foo');
|
||||
bc.render();
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
expect(bc.$el.find('.icon-shared').length).toEqual(0);
|
||||
expect(bc.$el.find('.shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.icon-public').length).toEqual(1);
|
||||
});
|
||||
it('Render shared if dir is shared by circle', function() {
|
||||
var dirInfo = new OC.Files.FileInfo({
|
||||
id: 42,
|
||||
path: '/foo',
|
||||
type: 'dir',
|
||||
shareTypes: [OC.Share.SHARE_TYPE_CIRCLE]
|
||||
});
|
||||
bc.setDirectoryInfo(dirInfo);
|
||||
bc.setDirectory('/foo');
|
||||
bc.render();
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
expect(bc.$el.find('.icon-shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.icon-public').length).toEqual(0);
|
||||
});
|
||||
it('Render shared if dir is shared with remote', function() {
|
||||
var dirInfo = new OC.Files.FileInfo({
|
||||
id: 42,
|
||||
path: '/foo',
|
||||
type: 'dir',
|
||||
shareTypes: [OC.Share.SHARE_TYPE_REMOTE]
|
||||
});
|
||||
bc.setDirectoryInfo(dirInfo);
|
||||
bc.setDirectory('/foo');
|
||||
bc.render();
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
expect(bc.$el.find('.icon-shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.icon-public').length).toEqual(0);
|
||||
});
|
||||
it('Render link shared if at least one is a link share', function() {
|
||||
var dirInfo = new OC.Files.FileInfo({
|
||||
id: 42,
|
||||
path: '/foo',
|
||||
type: 'dir',
|
||||
shareTypes: [
|
||||
OC.Share.SHARE_TYPE_USER,
|
||||
OC.Share.SHARE_TYPE_GROUP,
|
||||
OC.Share.SHARE_TYPE_LINK,
|
||||
OC.Share.SHARE_TYPE_EMAIL,
|
||||
OC.Share.SHARE_TYPE_REMOTE,
|
||||
OC.Share.SHARE_TYPE_CIRCLE
|
||||
]
|
||||
});
|
||||
bc.setDirectoryInfo(dirInfo);
|
||||
bc.setDirectory('/foo');
|
||||
bc.render();
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
expect(bc.$el.find('.icon-shared').length).toEqual(0);
|
||||
expect(bc.$el.find('.shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.icon-public').length).toEqual(1);
|
||||
});
|
||||
it('Remove shared status from user share', function() {
|
||||
var dirInfo = new OC.Files.FileInfo({
|
||||
id: 42,
|
||||
path: '/foo',
|
||||
type: 'dir',
|
||||
shareTypes: [OC.Share.SHARE_TYPE_USER]
|
||||
});
|
||||
|
||||
bc.setDirectory('/foo');
|
||||
bc.setDirectoryInfo(dirInfo);
|
||||
bc.render();
|
||||
|
||||
var mock = sinon.createStubInstance(OCA.Files.FileList);
|
||||
mock.showDetailsView = function() { };
|
||||
OCA.Files.App.fileList = mock;
|
||||
var spy = sinon.spy(mock, 'showDetailsView');
|
||||
bc.$el.find('.icon-shared').click();
|
||||
|
||||
expect(spy.calledOnce).toEqual(true);
|
||||
|
||||
var model = sinon.createStubInstance(OC.Share.ShareItemModel);
|
||||
model.getSharesWithCurrentItem = function() { return [] };
|
||||
model.hasLinkShares = function() { return false; };
|
||||
|
||||
shareTab.trigger('sharesChanged', model);
|
||||
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
expect(bc.$el.find('.icon-shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.shared').length).toEqual(0);
|
||||
expect(bc.$el.find('.icon-public').length).toEqual(0);
|
||||
});
|
||||
it('Add link share to user share', function() {
|
||||
var dirInfo = new OC.Files.FileInfo({
|
||||
id: 42,
|
||||
path: '/foo',
|
||||
type: 'dir',
|
||||
shareTypes: [OC.Share.SHARE_TYPE_USER]
|
||||
});
|
||||
|
||||
bc.setDirectory('/foo');
|
||||
bc.setDirectoryInfo(dirInfo);
|
||||
bc.render();
|
||||
|
||||
var mock = sinon.createStubInstance(OCA.Files.FileList);
|
||||
mock.showDetailsView = function() { };
|
||||
OCA.Files.App.fileList = mock;
|
||||
var spy = sinon.spy(mock, 'showDetailsView');
|
||||
bc.$el.find('.icon-shared').click();
|
||||
|
||||
expect(spy.calledOnce).toEqual(true);
|
||||
|
||||
var model = sinon.createStubInstance(OC.Share.ShareItemModel);
|
||||
model.getSharesWithCurrentItem = function() { return [
|
||||
{share_type: OC.Share.SHARE_TYPE_USER}
|
||||
] };
|
||||
model.hasLinkShares = function() { return true; };
|
||||
|
||||
shareTab.trigger('sharesChanged', model);
|
||||
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
expect(bc.$el.find('.icon-shared').length).toEqual(0);
|
||||
expect(bc.$el.find('.shared').length).toEqual(1);
|
||||
expect(bc.$el.find('.icon-public').length).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,784 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3
|
||||
* or later.
|
||||
*
|
||||
* See the COPYING-README file.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('OCA.Sharing.FileList tests', function() {
|
||||
var testFiles, alertStub, notificationStub, fileList;
|
||||
|
||||
beforeEach(function() {
|
||||
alertStub = sinon.stub(OC.dialogs, 'alert');
|
||||
notificationStub = sinon.stub(OC.Notification, 'show');
|
||||
|
||||
// init parameters and test table elements
|
||||
$('#testArea').append(
|
||||
'<div id="app-content-container">' +
|
||||
// init horrible parameters
|
||||
'<input type="hidden" id="dir" value="/"></input>' +
|
||||
'<input type="hidden" id="permissions" value="31"></input>' +
|
||||
// dummy controls
|
||||
'<div id="controls">' +
|
||||
' <div class="actions creatable"></div>' +
|
||||
' <div class="notCreatable"></div>' +
|
||||
'</div>' +
|
||||
// dummy table
|
||||
// TODO: at some point this will be rendered by the fileList class itself!
|
||||
'<table id="filestable" class="list-container view-grid">' +
|
||||
'<thead><tr>' +
|
||||
'<th id="headerName" class="hidden column-name">' +
|
||||
'<input type="checkbox" id="select_all_files" class="select-all">' +
|
||||
'<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' +
|
||||
'<span class="selectedActions hidden">' +
|
||||
'</th>' +
|
||||
'<th class="hidden column-mtime">' +
|
||||
'<a class="columntitle" data-sort="mtime"><span class="sort-indicator"></span></a>' +
|
||||
'</th>' +
|
||||
'<th class="column-expiration">' +
|
||||
'<a class="columntitle"><span>Expiration date</span></a>' +
|
||||
'</th>' +
|
||||
'</tr></thead>' +
|
||||
'<tbody id="fileList"></tbody>' +
|
||||
'<tfoot></tfoot>' +
|
||||
'</table>' +
|
||||
'<div id="emptycontent">Empty content message</div>' +
|
||||
'</div>'
|
||||
);
|
||||
|
||||
OC.Plugins.register('OCA.Files.FileList', OCA.Files.TagsPlugin);
|
||||
});
|
||||
afterEach(function() {
|
||||
testFiles = undefined;
|
||||
fileList.destroy();
|
||||
fileList = undefined;
|
||||
|
||||
notificationStub.restore();
|
||||
alertStub.restore();
|
||||
});
|
||||
|
||||
describe('loading file list for incoming shares', function() {
|
||||
var ocsResponse;
|
||||
var ocsResponseRemote;
|
||||
|
||||
beforeEach(function() {
|
||||
fileList = new OCA.Sharing.FileList(
|
||||
$('#app-content-container'), {
|
||||
sharedWithUser: true
|
||||
}
|
||||
);
|
||||
OCA.Sharing.Util.attach(fileList);
|
||||
|
||||
fileList.reload();
|
||||
|
||||
/* jshint camelcase: false */
|
||||
ocsResponse = {
|
||||
ocs: {
|
||||
meta: {
|
||||
status: 'ok',
|
||||
statuscode: 100,
|
||||
message: null
|
||||
},
|
||||
data: [{
|
||||
id: 7,
|
||||
item_type: 'file',
|
||||
item_source: 49,
|
||||
item_target: '/49',
|
||||
file_source: 49,
|
||||
file_target: '/local path/local name.txt',
|
||||
path: 'files/something shared.txt',
|
||||
permissions: 31,
|
||||
stime: 11111,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user1',
|
||||
share_with_displayname: 'User One',
|
||||
tags: [OC.TAG_FAVORITE],
|
||||
mimetype: 'text/plain',
|
||||
uid_owner: 'user2',
|
||||
displayname_owner: 'User Two'
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
/* jshint camelcase: false */
|
||||
ocsResponseRemote = {
|
||||
ocs: {
|
||||
meta: {
|
||||
status: 'ok',
|
||||
statuscode: 100,
|
||||
message: null
|
||||
},
|
||||
data: [{
|
||||
id: 8,
|
||||
remote: 'https://foo.bar/',
|
||||
remote_id: 42,
|
||||
share_token: 'abc',
|
||||
name: '/a.txt',
|
||||
owner: 'user3',
|
||||
user: 'user1',
|
||||
mountpoint: '/b.txt',
|
||||
mountpoint_hash: 'def',
|
||||
accepted: 1,
|
||||
mimetype: 'text/plain',
|
||||
mtime: 22222,
|
||||
permissions: 31,
|
||||
type: 'file',
|
||||
file_id: 1337
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
it('render file shares', function() {
|
||||
expect(fakeServer.requests.length).toEqual(2);
|
||||
expect(fakeServer.requests[0].url).toEqual(
|
||||
OC.linkToOCS('apps/files_sharing/api/v1') +
|
||||
'shares?format=json&shared_with_me=true&include_tags=true'
|
||||
);
|
||||
|
||||
expect(fakeServer.requests[1].url).toEqual(
|
||||
OC.linkToOCS('apps/files_sharing/api/v1') +
|
||||
'remote_shares?format=json&include_tags=true'
|
||||
);
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(ocsResponse)
|
||||
);
|
||||
|
||||
fakeServer.requests[1].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(ocsResponseRemote)
|
||||
);
|
||||
|
||||
var $rows = fileList.$el.find('tbody tr');
|
||||
expect($rows.length).toEqual(2);
|
||||
|
||||
var $tr = $rows.eq(0);
|
||||
expect($tr.attr('data-id')).toEqual('49');
|
||||
expect($tr.attr('data-type')).toEqual('file');
|
||||
expect($tr.attr('data-file')).toEqual('local name.txt');
|
||||
expect($tr.attr('data-path')).toEqual('/local path');
|
||||
expect($tr.attr('data-size')).not.toBeDefined();
|
||||
expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
|
||||
expect($tr.attr('data-mime')).toEqual('text/plain');
|
||||
expect($tr.attr('data-mtime')).toEqual('11111000');
|
||||
expect($tr.attr('data-share-owner')).toEqual('User Two');
|
||||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.attr('data-favorite')).toEqual('true');
|
||||
expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE);
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.getRootPath() +
|
||||
'/remote.php/webdav/local%20path/local%20name.txt'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
|
||||
$tr = $rows.eq(1);
|
||||
expect($tr.attr('data-id')).toEqual('1337');
|
||||
expect($tr.attr('data-type')).toEqual('file');
|
||||
expect($tr.attr('data-file')).toEqual('b.txt');
|
||||
expect($tr.attr('data-path')).toEqual('');
|
||||
expect($tr.attr('data-size')).not.toBeDefined();
|
||||
expect(parseInt($tr.attr('data-permissions'), 10))
|
||||
.toEqual(OC.PERMISSION_ALL); // read and delete
|
||||
expect($tr.attr('data-mime')).toEqual('text/plain');
|
||||
expect($tr.attr('data-mtime')).toEqual('22222000');
|
||||
expect($tr.attr('data-share-owner')).toEqual('user3@foo.bar/');
|
||||
expect($tr.attr('data-share-id')).toEqual('8');
|
||||
expect($tr.attr('data-favorite')).not.toBeDefined();
|
||||
expect($tr.attr('data-tags')).toEqual('');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.getRootPath() +
|
||||
'/remote.php/webdav/b.txt'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('b.txt');
|
||||
});
|
||||
it('render folder shares', function() {
|
||||
/* jshint camelcase: false */
|
||||
ocsResponse.ocs.data[0] = _.extend(ocsResponse.ocs.data[0], {
|
||||
item_type: 'folder',
|
||||
file_target: '/local path/local name',
|
||||
path: 'files/something shared',
|
||||
});
|
||||
|
||||
ocsResponseRemote.ocs.data[0] = _.extend(ocsResponseRemote.ocs.data[0], {
|
||||
type: 'dir',
|
||||
mimetype: 'httpd/unix-directory',
|
||||
name: '/a',
|
||||
mountpoint: '/b'
|
||||
});
|
||||
|
||||
expect(fakeServer.requests.length).toEqual(2);
|
||||
expect(fakeServer.requests[0].url).toEqual(
|
||||
OC.linkToOCS('apps/files_sharing/api/v1') +
|
||||
'shares?format=json&shared_with_me=true&include_tags=true'
|
||||
);
|
||||
expect(fakeServer.requests[1].url).toEqual(
|
||||
OC.linkToOCS('apps/files_sharing/api/v1') +
|
||||
'remote_shares?format=json&include_tags=true'
|
||||
);
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(ocsResponse)
|
||||
);
|
||||
fakeServer.requests[1].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(ocsResponseRemote)
|
||||
);
|
||||
|
||||
var $rows = fileList.$el.find('tbody tr');
|
||||
expect($rows.length).toEqual(2);
|
||||
|
||||
var $tr = $rows.eq(0);
|
||||
expect($tr.attr('data-id')).toEqual('49');
|
||||
expect($tr.attr('data-type')).toEqual('dir');
|
||||
expect($tr.attr('data-file')).toEqual('local name');
|
||||
expect($tr.attr('data-path')).toEqual('/local path');
|
||||
expect($tr.attr('data-size')).not.toBeDefined();
|
||||
expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
|
||||
expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
|
||||
expect($tr.attr('data-mtime')).toEqual('11111000');
|
||||
expect($tr.attr('data-share-owner')).toEqual('User Two');
|
||||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.attr('data-favorite')).toEqual('true');
|
||||
expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE);
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.getRootPath() +
|
||||
'/index.php/apps/files' +
|
||||
'?dir=/local%20path/local%20name'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name');
|
||||
|
||||
$tr = $rows.eq(1);
|
||||
expect($tr.attr('data-id')).toEqual('1337');
|
||||
expect($tr.attr('data-type')).toEqual('dir');
|
||||
expect($tr.attr('data-file')).toEqual('b');
|
||||
expect($tr.attr('data-path')).toEqual('');
|
||||
expect($tr.attr('data-size')).not.toBeDefined();
|
||||
expect(parseInt($tr.attr('data-permissions'), 10))
|
||||
.toEqual(OC.PERMISSION_ALL); // read and delete
|
||||
expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
|
||||
expect($tr.attr('data-mtime')).toEqual('22222000');
|
||||
expect($tr.attr('data-share-owner')).toEqual('user3@foo.bar/');
|
||||
expect($tr.attr('data-share-id')).toEqual('8');
|
||||
expect($tr.attr('data-favorite')).not.toBeDefined();
|
||||
expect($tr.attr('data-tags')).toEqual('');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.getRootPath() +
|
||||
'/index.php/apps/files' +
|
||||
'?dir=/b'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('b');
|
||||
|
||||
});
|
||||
});
|
||||
describe('loading file list for outgoing shares', function() {
|
||||
var ocsResponse;
|
||||
|
||||
beforeEach(function() {
|
||||
fileList = new OCA.Sharing.FileList(
|
||||
$('#app-content-container'), {
|
||||
sharedWithUser: false
|
||||
}
|
||||
);
|
||||
OCA.Sharing.Util.attach(fileList);
|
||||
|
||||
fileList.reload();
|
||||
|
||||
/* jshint camelcase: false */
|
||||
ocsResponse = {
|
||||
ocs: {
|
||||
meta: {
|
||||
status: 'ok',
|
||||
statuscode: 100,
|
||||
message: null
|
||||
},
|
||||
data: [{
|
||||
id: 7,
|
||||
item_type: 'file',
|
||||
item_source: 49,
|
||||
file_source: 49,
|
||||
path: '/local path/local name.txt',
|
||||
permissions: 27,
|
||||
stime: 11111,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user2',
|
||||
share_with_displayname: 'User Two',
|
||||
tags: [OC.TAG_FAVORITE],
|
||||
mimetype: 'text/plain',
|
||||
uid_owner: 'user1',
|
||||
displayname_owner: 'User One'
|
||||
}]
|
||||
}
|
||||
};
|
||||
});
|
||||
it('render file shares', function() {
|
||||
var request;
|
||||
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(
|
||||
OC.linkToOCS('apps/files_sharing/api/v1') +
|
||||
'shares?format=json&shared_with_me=false&include_tags=true'
|
||||
);
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(ocsResponse)
|
||||
);
|
||||
|
||||
var $rows = fileList.$el.find('tbody tr');
|
||||
var $tr = $rows.eq(0);
|
||||
expect($rows.length).toEqual(1);
|
||||
expect($tr.attr('data-id')).toEqual('49');
|
||||
expect($tr.attr('data-type')).toEqual('file');
|
||||
expect($tr.attr('data-file')).toEqual('local name.txt');
|
||||
expect($tr.attr('data-path')).toEqual('/local path');
|
||||
expect($tr.attr('data-size')).not.toBeDefined();
|
||||
expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
|
||||
expect($tr.attr('data-mime')).toEqual('text/plain');
|
||||
expect($tr.attr('data-mtime')).toEqual('11111000');
|
||||
expect($tr.attr('data-share-owner')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.attr('data-favorite')).toEqual('true');
|
||||
expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE);
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.getRootPath() +
|
||||
'/remote.php/webdav/local%20path/local%20name.txt'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
});
|
||||
it('render folder shares', function() {
|
||||
var request;
|
||||
/* jshint camelcase: false */
|
||||
ocsResponse.ocs.data[0] = _.extend(ocsResponse.ocs.data[0], {
|
||||
item_type: 'folder',
|
||||
path: '/local path/local name',
|
||||
});
|
||||
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(
|
||||
OC.linkToOCS('apps/files_sharing/api/v1') +
|
||||
'shares?format=json&shared_with_me=false&include_tags=true'
|
||||
);
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(ocsResponse)
|
||||
);
|
||||
|
||||
var $rows = fileList.$el.find('tbody tr');
|
||||
var $tr = $rows.eq(0);
|
||||
expect($rows.length).toEqual(1);
|
||||
expect($tr.attr('data-id')).toEqual('49');
|
||||
expect($tr.attr('data-type')).toEqual('dir');
|
||||
expect($tr.attr('data-file')).toEqual('local name');
|
||||
expect($tr.attr('data-path')).toEqual('/local path');
|
||||
expect($tr.attr('data-size')).not.toBeDefined();
|
||||
expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
|
||||
expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
|
||||
expect($tr.attr('data-mtime')).toEqual('11111000');
|
||||
expect($tr.attr('data-share-owner')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.attr('data-favorite')).toEqual('true');
|
||||
expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE);
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.getRootPath() +
|
||||
'/index.php/apps/files' +
|
||||
'?dir=/local%20path/local%20name'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name');
|
||||
});
|
||||
it('render link shares', function() {
|
||||
/* jshint camelcase: false */
|
||||
var request;
|
||||
ocsResponse.ocs.data[0] = {
|
||||
id: 7,
|
||||
item_type: 'file',
|
||||
item_source: 49,
|
||||
file_source: 49,
|
||||
path: '/local path/local name.txt',
|
||||
permissions: 1,
|
||||
stime: 11111,
|
||||
share_type: OC.Share.SHARE_TYPE_LINK,
|
||||
share_with: null,
|
||||
token: 'abc',
|
||||
mimetype: 'text/plain',
|
||||
uid_owner: 'user1',
|
||||
displayname_owner: 'User One',
|
||||
tags: [OC.TAG_FAVORITE]
|
||||
};
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(
|
||||
OC.linkToOCS('apps/files_sharing/api/v1') +
|
||||
'shares?format=json&shared_with_me=false&include_tags=true'
|
||||
);
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(ocsResponse)
|
||||
);
|
||||
|
||||
var $rows = fileList.$el.find('tbody tr');
|
||||
var $tr = $rows.eq(0);
|
||||
expect($rows.length).toEqual(1);
|
||||
expect($tr.attr('data-id')).toEqual('49');
|
||||
expect($tr.attr('data-type')).toEqual('file');
|
||||
expect($tr.attr('data-file')).toEqual('local name.txt');
|
||||
expect($tr.attr('data-path')).toEqual('/local path');
|
||||
expect($tr.attr('data-size')).not.toBeDefined();
|
||||
expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
|
||||
expect($tr.attr('data-mime')).toEqual('text/plain');
|
||||
expect($tr.attr('data-mtime')).toEqual('11111000');
|
||||
expect($tr.attr('data-share-owner')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.attr('data-favorite')).toEqual('true');
|
||||
expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE);
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.getRootPath() + '/remote.php/webdav/local%20path/local%20name.txt'
|
||||
);
|
||||
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
});
|
||||
it('groups link shares with regular shares', function() {
|
||||
/* jshint camelcase: false */
|
||||
var request;
|
||||
// link share
|
||||
ocsResponse.ocs.data.push({
|
||||
id: 8,
|
||||
item_type: 'file',
|
||||
item_source: 49,
|
||||
file_source: 49,
|
||||
path: '/local path/local name.txt',
|
||||
permissions: 1,
|
||||
stime: 11111,
|
||||
share_type: OC.Share.SHARE_TYPE_LINK,
|
||||
share_with: null,
|
||||
token: 'abc',
|
||||
mimetype: 'text/plain',
|
||||
uid_owner: 'user1',
|
||||
displayname_owner: 'User One',
|
||||
tags: [OC.TAG_FAVORITE],
|
||||
});
|
||||
// another share of the same file
|
||||
ocsResponse.ocs.data.push({
|
||||
id: 9,
|
||||
item_type: 'file',
|
||||
item_source: 49,
|
||||
file_source: 49,
|
||||
path: '/local path/local name.txt',
|
||||
permissions: 27,
|
||||
stime: 22222,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user3',
|
||||
share_with_displayname: 'User Three',
|
||||
mimetype: 'text/plain',
|
||||
uid_owner: 'user1',
|
||||
displayname_owner: 'User One'
|
||||
});
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(
|
||||
OC.linkToOCS('apps/files_sharing/api/v1') +
|
||||
'shares?format=json&shared_with_me=false&include_tags=true'
|
||||
);
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(ocsResponse)
|
||||
);
|
||||
|
||||
var $rows = fileList.$el.find('tbody tr');
|
||||
var $tr = $rows.eq(0);
|
||||
expect($rows.length).toEqual(1);
|
||||
expect($tr.attr('data-id')).toEqual('49');
|
||||
expect($tr.attr('data-type')).toEqual('file');
|
||||
expect($tr.attr('data-file')).toEqual('local name.txt');
|
||||
expect($tr.attr('data-path')).toEqual('/local path');
|
||||
expect($tr.attr('data-size')).not.toBeDefined();
|
||||
expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
|
||||
expect($tr.attr('data-mime')).toEqual('text/plain');
|
||||
// always use the most recent stime
|
||||
expect($tr.attr('data-mtime')).toEqual('22222000');
|
||||
expect($tr.attr('data-share-owner')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-id')).toEqual('7,8,9');
|
||||
expect($tr.attr('data-favorite')).toEqual('true');
|
||||
expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE);
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.getRootPath() + '/remote.php/webdav/local%20path/local%20name.txt'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
});
|
||||
});
|
||||
describe('loading file list for link shares', function() {
|
||||
var ocsResponse;
|
||||
|
||||
beforeEach(function() {
|
||||
fileList = new OCA.Sharing.FileList(
|
||||
$('#app-content-container'), {
|
||||
linksOnly: true
|
||||
}
|
||||
);
|
||||
OCA.Sharing.Util.attach(fileList);
|
||||
|
||||
fileList.reload();
|
||||
|
||||
var expirationDateInADay = moment()
|
||||
.add(1, 'days').format('YYYY-MM-DD HH:mm:ss');
|
||||
|
||||
/* jshint camelcase: false */
|
||||
ocsResponse = {
|
||||
ocs: {
|
||||
meta: {
|
||||
status: 'ok',
|
||||
statuscode: 100,
|
||||
message: null
|
||||
},
|
||||
data: [{
|
||||
id: 7,
|
||||
item_type: 'file',
|
||||
item_source: 49,
|
||||
file_source: 49,
|
||||
path: '/local path/local name.txt',
|
||||
permissions: 1,
|
||||
stime: 11111,
|
||||
expiration: null,
|
||||
share_type: OC.Share.SHARE_TYPE_LINK,
|
||||
share_with: null,
|
||||
token: 'abc',
|
||||
mimetype: 'text/plain',
|
||||
uid_owner: 'user1',
|
||||
displayname_owner: 'User One',
|
||||
tags: [OC.TAG_FAVORITE]
|
||||
},{
|
||||
id: 8,
|
||||
item_type: 'file',
|
||||
item_source: 50,
|
||||
file_source: 50,
|
||||
path: '/local path2/local name2.txt',
|
||||
permissions: 1,
|
||||
stime: 11112,
|
||||
expiration: expirationDateInADay,
|
||||
share_type: OC.Share.SHARE_TYPE_LINK,
|
||||
share_with: null,
|
||||
token: 'abcd',
|
||||
mimetype: 'text/plain2',
|
||||
uid_owner: 'user2',
|
||||
displayname_owner: 'User One2'
|
||||
}]
|
||||
}
|
||||
};
|
||||
});
|
||||
it('render only link shares', function() {
|
||||
/* jshint camelcase: false */
|
||||
var request;
|
||||
ocsResponse.ocs.data.push({
|
||||
// non-link share
|
||||
id: 8,
|
||||
item_type: 'file',
|
||||
item_source: 49,
|
||||
file_source: 49,
|
||||
path: '/local path/local name.txt',
|
||||
permissions: 27,
|
||||
stime: 11111,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user2',
|
||||
share_with_displayname: 'User Two',
|
||||
mimetype: 'text/plain',
|
||||
uid_owner: 'user1',
|
||||
displayname_owner: 'User One',
|
||||
tags: [OC.TAG_FAVORITE]
|
||||
});
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(
|
||||
OC.linkToOCS('apps/files_sharing/api/v1') +
|
||||
'shares?format=json&shared_with_me=false&include_tags=true'
|
||||
);
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(ocsResponse)
|
||||
);
|
||||
|
||||
// only renders the link share entries
|
||||
var $rows = fileList.$el.find('tbody tr');
|
||||
var $tr = $rows.eq(0);
|
||||
expect($rows.length).toEqual(2);
|
||||
expect($tr.attr('data-id')).toEqual('49');
|
||||
expect($tr.attr('data-type')).toEqual('file');
|
||||
expect($tr.attr('data-file')).toEqual('local name.txt');
|
||||
expect($tr.attr('data-path')).toEqual('/local path');
|
||||
expect($tr.attr('data-size')).not.toBeDefined();
|
||||
expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
|
||||
expect($tr.attr('data-mime')).toEqual('text/plain');
|
||||
expect($tr.attr('data-mtime')).toEqual('11111000');
|
||||
expect($tr.attr('data-share-recipient-data')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-owner')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.attr('data-favorite')).toEqual('true');
|
||||
expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE);
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.getRootPath() + '/remote.php/webdav/local%20path/local%20name.txt'
|
||||
);
|
||||
expect($tr.attr('data-expiration')).toEqual('0');
|
||||
expect($tr.find('td:last-child span').text()).toEqual('');
|
||||
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
|
||||
// change to next row
|
||||
$tr = $rows.eq(1);
|
||||
expect($tr.attr('data-id')).toEqual('50');
|
||||
expect($tr.attr('data-file')).toEqual('local name2.txt');
|
||||
expect($tr.attr('data-expiration')).not.toEqual('0');
|
||||
expect($tr.attr('data-favorite')).not.toBeDefined();
|
||||
expect($tr.attr('data-tags')).toEqual('');
|
||||
expect($tr.find('td:last-child span').text()).toEqual('in a day');
|
||||
});
|
||||
it('does not show virtual token recipient as recipient when password was set', function() {
|
||||
/* jshint camelcase: false */
|
||||
var request;
|
||||
// when a password is set, share_with contains an auth token
|
||||
ocsResponse.ocs.data[0].share_with = 'abc01234/01234abc';
|
||||
ocsResponse.ocs.data[0].share_with_displayname = 'abc01234/01234abc';
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(
|
||||
OC.linkToOCS('apps/files_sharing/api/v1') +
|
||||
'shares?format=json&shared_with_me=false&include_tags=true'
|
||||
);
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(ocsResponse)
|
||||
);
|
||||
|
||||
// only renders the link share entry
|
||||
var $rows = fileList.$el.find('tbody tr');
|
||||
var $tr = $rows.eq(0);
|
||||
expect($rows.length).toEqual(2);
|
||||
expect($tr.attr('data-id')).toEqual('49');
|
||||
expect($tr.attr('data-type')).toEqual('file');
|
||||
expect($tr.attr('data-file')).toEqual('local name.txt');
|
||||
expect($tr.attr('data-path')).toEqual('/local path');
|
||||
expect($tr.attr('data-size')).not.toBeDefined();
|
||||
expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
|
||||
expect($tr.attr('data-mime')).toEqual('text/plain');
|
||||
expect($tr.attr('data-mtime')).toEqual('11111000');
|
||||
expect($tr.attr('data-share-recipient-data')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-owner')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.attr('data-favorite')).toEqual('true');
|
||||
expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE);
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.getRootPath() +
|
||||
'/remote.php/webdav/local%20path/local%20name.txt');
|
||||
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
});
|
||||
});
|
||||
describe('setting share permissions for files', function () {
|
||||
beforeEach(function () {
|
||||
|
||||
var $content = $('<div id="content"></div>');
|
||||
$('#testArea').append($content);
|
||||
// dummy file list
|
||||
var $div = $(
|
||||
'<div>' +
|
||||
'<table id="filestable" class="list-container view-grid">' +
|
||||
'<thead></thead>' +
|
||||
'<tbody id="fileList"></tbody>' +
|
||||
'</table>' +
|
||||
'</div>');
|
||||
$('#content').append($div);
|
||||
|
||||
fileList = new OCA.Files.FileList($div);
|
||||
OCA.Sharing.Util.attach(fileList);
|
||||
});
|
||||
|
||||
it('external storage root folder', function () {
|
||||
var $tr;
|
||||
OC.Share.statuses = {1: {link: false, path: '/subdir'}};
|
||||
fileList.setFiles([{
|
||||
id: 1,
|
||||
type: 'dir',
|
||||
name: 'One.txt',
|
||||
path: '/subdir',
|
||||
mimetype: 'text/plain',
|
||||
size: 12,
|
||||
permissions: OC.PERMISSION_READ,
|
||||
sharePermissions: OC.PERMISSION_READ,
|
||||
etag: 'abc',
|
||||
shareOwner: 'User One',
|
||||
recipients: 'User Two',
|
||||
mountType: 'external-root',
|
||||
sharePermissions: OC.PERMISSION_READ,
|
||||
}]);
|
||||
$tr = fileList.$el.find('tr:first');
|
||||
|
||||
expect(parseInt($tr.attr('data-share-permissions'), 10)).toEqual(OC.PERMISSION_READ);
|
||||
});
|
||||
|
||||
it('external storage root folder reshare', function () {
|
||||
var $tr;
|
||||
OC.Share.statuses = {1: {link: false, path: '/subdir'}};
|
||||
fileList.setFiles([{
|
||||
id: 1,
|
||||
type: 'dir',
|
||||
name: 'One.txt',
|
||||
path: '/subdir',
|
||||
mimetype: 'text/plain',
|
||||
size: 12,
|
||||
permissions: OC.PERMISSION_READ + OC.PERMISSION_SHARE,
|
||||
sharePermissions: OC.PERMISSION_READ + OC.PERMISSION_SHARE,
|
||||
etag: 'abc',
|
||||
shareOwner: 'User One',
|
||||
recipients: 'User Two',
|
||||
mountType: 'external-root',
|
||||
sharePermissions: OC.PERMISSION_READ | OC.PERMISSION_SHARE,
|
||||
}]);
|
||||
$tr = fileList.$el.find('tr:first');
|
||||
|
||||
expect(parseInt($tr.attr('data-share-permissions'), 10)).toEqual(OC.PERMISSION_READ + OC.PERMISSION_SHARE);
|
||||
});
|
||||
|
||||
it('external storage root folder file', function () {
|
||||
var $tr;
|
||||
OC.Share.statuses = {1: {link: false, path: '/subdir'}};
|
||||
fileList.setFiles([{
|
||||
id: 1,
|
||||
type: 'file',
|
||||
name: 'One.txt',
|
||||
path: '/subdir',
|
||||
mimetype: 'text/plain',
|
||||
size: 12,
|
||||
permissions: OC.PERMISSION_READ,
|
||||
sharePermissions: OC.PERMISSION_READ,
|
||||
etag: 'abc',
|
||||
shareOwner: 'User One',
|
||||
recipients: 'User Two',
|
||||
mountType: 'external-root'
|
||||
}]);
|
||||
$tr = fileList.$el.find('tr:first');
|
||||
|
||||
expect(parseInt($tr.attr('data-share-permissions'), 10))
|
||||
.toEqual(OC.PERMISSION_READ);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,371 +0,0 @@
|
|||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Vincent Petry
|
||||
* @copyright 2014 Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('OC.Share tests', function() {
|
||||
describe('markFileAsShared', function() {
|
||||
var $file;
|
||||
var tooltipStub;
|
||||
|
||||
beforeEach(function() {
|
||||
tooltipStub = sinon.stub($.fn, 'tooltip');
|
||||
$file = $('<tr><td class="filename"><div class="thumbnail"></div><span class="name">File name</span></td></tr>');
|
||||
$file.find('.filename').append(
|
||||
'<span class="fileactions">' +
|
||||
'<a href="#" class="action action-share" data-action="Share">' +
|
||||
'<img></img><span> Share</span>' +
|
||||
'</a>' +
|
||||
'</span>'
|
||||
);
|
||||
});
|
||||
afterEach(function() {
|
||||
$file = null;
|
||||
tooltipStub.restore();
|
||||
});
|
||||
describe('displaying the share owner', function() {
|
||||
function checkOwner(input, output, title) {
|
||||
var $action;
|
||||
|
||||
$file.attr('data-share-owner', input);
|
||||
$file.attr('data-share-owner-id', input);
|
||||
OC.Share.markFileAsShared($file);
|
||||
|
||||
$action = $file.find('.action-share>span').parent();
|
||||
expect($action.text().trim()).toEqual(output);
|
||||
if (_.isString(title)) {
|
||||
expect($action.find('.remoteAddress').attr('title')).toEqual(title);
|
||||
} else {
|
||||
expect($action.find('.remoteAddress').attr('title')).not.toBeDefined();
|
||||
}
|
||||
expect(tooltipStub.calledOnce).toEqual(true);
|
||||
tooltipStub.reset();
|
||||
}
|
||||
|
||||
it('displays the local share owner with "Shared by" prefix', function() {
|
||||
checkOwner('User One', 'Shared by User One', null);
|
||||
});
|
||||
it('displays the user name part of a remote share owner', function() {
|
||||
checkOwner(
|
||||
'User One@someserver.com',
|
||||
'User One@…',
|
||||
'Shared by User One@someserver.com'
|
||||
);
|
||||
checkOwner(
|
||||
'User One@someserver.com/',
|
||||
'User One@…',
|
||||
'Shared by User One@someserver.com'
|
||||
);
|
||||
checkOwner(
|
||||
'User One@someserver.com/root/of/owncloud',
|
||||
'User One@…',
|
||||
'Shared by User One@someserver.com'
|
||||
);
|
||||
});
|
||||
it('displays the user name part with domain of a remote share owner', function() {
|
||||
checkOwner(
|
||||
'User One@example.com@someserver.com',
|
||||
'User One@example.com',
|
||||
'Shared by User One@example.com@someserver.com'
|
||||
);
|
||||
checkOwner(
|
||||
'User One@example.com@someserver.com/',
|
||||
'User One@example.com',
|
||||
'Shared by User One@example.com@someserver.com'
|
||||
);
|
||||
checkOwner(
|
||||
'User One@example.com@someserver.com/root/of/owncloud',
|
||||
'User One@example.com',
|
||||
'Shared by User One@example.com@someserver.com'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('displaying the folder icon', function() {
|
||||
function checkIcon(expectedImage) {
|
||||
var imageUrl = OC.TestUtil.getImageUrl($file.find('.filename .thumbnail'));
|
||||
expectedIcon = OC.imagePath('core', expectedImage);
|
||||
expect(imageUrl).toEqual(expectedIcon);
|
||||
}
|
||||
|
||||
it('shows a plain folder icon for non-shared folders', function() {
|
||||
$file.attr('data-type', 'dir');
|
||||
OC.Share.markFileAsShared($file);
|
||||
|
||||
checkIcon('filetypes/folder');
|
||||
});
|
||||
it('shows a shared folder icon for folders shared with another user', function() {
|
||||
$file.attr('data-type', 'dir');
|
||||
OC.Share.markFileAsShared($file, true);
|
||||
|
||||
checkIcon('filetypes/folder-shared');
|
||||
});
|
||||
it('shows a shared folder icon for folders shared with the current user', function() {
|
||||
$file.attr('data-type', 'dir');
|
||||
$file.attr('data-share-owner', 'someoneelse');
|
||||
$file.attr('data-share-owner-id', 'someoneelse');
|
||||
OC.Share.markFileAsShared($file);
|
||||
|
||||
checkIcon('filetypes/folder-shared');
|
||||
});
|
||||
it('shows a link folder icon for folders shared with link', function() {
|
||||
$file.attr('data-type', 'dir');
|
||||
OC.Share.markFileAsShared($file, false, true);
|
||||
|
||||
checkIcon('filetypes/folder-public');
|
||||
});
|
||||
it('shows a link folder icon for folders shared with both link and another user', function() {
|
||||
$file.attr('data-type', 'dir');
|
||||
OC.Share.markFileAsShared($file, true, true);
|
||||
|
||||
checkIcon('filetypes/folder-public');
|
||||
});
|
||||
it('shows a link folder icon for folders reshared with link', function() {
|
||||
$file.attr('data-type', 'dir');
|
||||
$file.attr('data-share-owner', 'someoneelse');
|
||||
OC.Share.markFileAsShared($file, false, true);
|
||||
|
||||
checkIcon('filetypes/folder-public');
|
||||
});
|
||||
it('shows external storage icon if external mount point', function() {
|
||||
$file.attr('data-type', 'dir');
|
||||
$file.attr('data-mountType', 'external');
|
||||
OC.Share.markFileAsShared($file, false, false);
|
||||
|
||||
checkIcon('filetypes/folder-external');
|
||||
});
|
||||
it('shows encrypted icon if encrypted folder', function() {
|
||||
$file.attr('data-type', 'dir');
|
||||
$file.attr('data-e2eencrypted', true);
|
||||
OC.Share.markFileAsShared($file, false, false);
|
||||
|
||||
checkIcon('filetypes/folder-encrypted');
|
||||
});
|
||||
});
|
||||
|
||||
describe('displaying the recipients', function() {
|
||||
function checkRecipients(input, output, title) {
|
||||
var $action;
|
||||
|
||||
$file.attr('data-share-recipient-data', JSON.stringify(input));
|
||||
OC.Share.markFileAsShared($file, true);
|
||||
|
||||
$action = $file.find('.action-share>span').parent();
|
||||
expect($action.text().trim()).toEqual(output);
|
||||
if (_.isString(title)) {
|
||||
expect($action.find('.remoteAddress').attr('title')).toEqual(title);
|
||||
} else if (_.isArray(title)) {
|
||||
var tooltips = $action.find('.remoteAddress');
|
||||
expect(tooltips.length).toEqual(title.length);
|
||||
|
||||
tooltips.each(function(i) {
|
||||
expect($(this).attr('title')).toEqual(title[i]);
|
||||
});
|
||||
} else {
|
||||
expect($action.find('.remoteAddress').attr('title')).not.toBeDefined();
|
||||
}
|
||||
expect(tooltipStub.calledOnce).toEqual(true);
|
||||
tooltipStub.reset();
|
||||
}
|
||||
|
||||
it('displays the local share owner as is', function() {
|
||||
var input = {
|
||||
0: {
|
||||
shareWith: 'User One',
|
||||
shareWithDisplayName: 'User One'
|
||||
}
|
||||
};
|
||||
checkRecipients(input, 'Shared with User One', null);
|
||||
});
|
||||
it('displays the user name part of a remote recipient', function() {
|
||||
var input = {
|
||||
0: {
|
||||
shareWith: 'User One@someserver.com',
|
||||
shareWithDisplayName: 'User One@someserver.com'
|
||||
}
|
||||
};
|
||||
checkRecipients(
|
||||
input,
|
||||
'User One@…',
|
||||
'Shared with User One@someserver.com'
|
||||
);
|
||||
|
||||
input = {
|
||||
0: {
|
||||
shareWith: 'User One@someserver.com/',
|
||||
shareWithDisplayName: 'User One@someserver.com/'
|
||||
}
|
||||
};
|
||||
checkRecipients(
|
||||
input,
|
||||
'User One@…',
|
||||
'Shared with User One@someserver.com'
|
||||
);
|
||||
|
||||
input = {
|
||||
0: {
|
||||
shareWith: 'User One@someserver.com/root/of/nextcloud',
|
||||
shareWithDisplayName: 'User One@someserver.com/root/of/nextcloud'
|
||||
}
|
||||
};
|
||||
checkRecipients(
|
||||
input,
|
||||
'User One@…',
|
||||
'Shared with User One@someserver.com'
|
||||
);
|
||||
});
|
||||
it('displays the user name part with domain of a remote share owner', function() {
|
||||
var input = {
|
||||
0: {
|
||||
shareWith: 'User One@example.com@someserver.com',
|
||||
shareWithDisplayName: 'User One@example.com@someserver.com'
|
||||
}
|
||||
};
|
||||
checkRecipients(
|
||||
input,
|
||||
'User One@example.com',
|
||||
'Shared with User One@example.com@someserver.com'
|
||||
);
|
||||
|
||||
input = {
|
||||
0: {
|
||||
shareWith: 'User One@example.com@someserver.com/',
|
||||
shareWithDisplayName: 'User One@example.com@someserver.com/'
|
||||
}
|
||||
};
|
||||
checkRecipients(
|
||||
input,
|
||||
'User One@example.com',
|
||||
'Shared with User One@example.com@someserver.com'
|
||||
);
|
||||
|
||||
input = {
|
||||
0: {
|
||||
shareWith: 'User One@example.com@someserver.com/root/of/nextcloud',
|
||||
shareWithDisplayName: 'User One@example.com@someserver.com/root/of/nextcloud'
|
||||
}
|
||||
};
|
||||
checkRecipients(
|
||||
input,
|
||||
'User One@example.com',
|
||||
'Shared with User One@example.com@someserver.com'
|
||||
);
|
||||
});
|
||||
it('display multiple remote recipients', function() {
|
||||
var input = {
|
||||
0: {
|
||||
shareWith: 'One@someserver.com',
|
||||
shareWithDisplayName: 'One@someserver.com'
|
||||
},
|
||||
1: {
|
||||
shareWith: 'two@otherserver.com',
|
||||
shareWithDisplayName: 'two@otherserver.com'
|
||||
}
|
||||
};
|
||||
checkRecipients(
|
||||
input,
|
||||
'One@… two@…',
|
||||
['Shared with One@someserver.com', 'Shared with two@otherserver.com']
|
||||
);
|
||||
|
||||
input = {
|
||||
0: {
|
||||
shareWith: 'One@someserver.com/',
|
||||
shareWithDisplayName: 'One@someserver.com/'
|
||||
},
|
||||
1: {
|
||||
shareWith: 'two@someserver.com',
|
||||
shareWithDisplayName: 'two@someserver.com'
|
||||
}
|
||||
};
|
||||
checkRecipients(
|
||||
input,
|
||||
'One@… two@…',
|
||||
['Shared with One@someserver.com', 'Shared with two@otherserver.com']
|
||||
);
|
||||
|
||||
input = {
|
||||
0: {
|
||||
shareWith: 'One@someserver.com/root/of/nextcloud',
|
||||
shareWithDisplayName: 'One@someserver.com/root/of/nextcloud'
|
||||
},
|
||||
1: {
|
||||
shareWith: 'two@someserver.com',
|
||||
shareWithDisplayName: 'two@someserver.com'
|
||||
}
|
||||
};
|
||||
checkRecipients(
|
||||
input,
|
||||
'One@… two@…',
|
||||
['Shared with One@someserver.com', 'Shared with two@otherserver.com']
|
||||
);
|
||||
});
|
||||
it('display mixed recipients', function() {
|
||||
checkRecipients(
|
||||
{
|
||||
0: {
|
||||
shareWith: 'One',
|
||||
shareWithDisplayName: 'One'
|
||||
},
|
||||
1: {
|
||||
shareWith: 'two@otherserver.com',
|
||||
shareWithDisplayName: 'two@otherserver.com'
|
||||
}
|
||||
},
|
||||
'Shared with One two@…',
|
||||
['Shared with two@otherserver.com']
|
||||
);
|
||||
});
|
||||
it('display multiple with divergent displaynames', function() {
|
||||
var recipients = {
|
||||
0: {
|
||||
shareWith: 'One',
|
||||
shareWithDisplayName: 'Yoko Ono',
|
||||
_output: 'Shared with Yoko Ono'
|
||||
},
|
||||
1: {
|
||||
shareWith: 'two@otherserver.com',
|
||||
shareWithDisplayName: 'two@othererver.com',
|
||||
_output: 'two@…'
|
||||
},
|
||||
2: {
|
||||
shareWith: 'Three',
|
||||
shareWithDisplayName: 'Green, Mina',
|
||||
_output: 'Shared with Green, Mina'
|
||||
}
|
||||
};
|
||||
|
||||
// we cannot assume the locale, also because PhantomJS has a bug.
|
||||
var sortArray = _.toArray(recipients)
|
||||
.sort(function(a, b) {
|
||||
return a.shareWithDisplayName.localeCompare(b.shareWithDisplayName);
|
||||
});
|
||||
var sortedOutput = _.map(sortArray, function(recipient) {
|
||||
return recipient._output;
|
||||
}).join(' ');
|
||||
|
||||
checkRecipients(
|
||||
recipients,
|
||||
sortedOutput,
|
||||
['Shared with two@otherserver.com']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,349 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* @copyright Copyright (c) 2015, Tom Needham (tom@owncloud.com)
|
||||
* @copyright Copyright (c) 2017, Daniel Calviño Sánchez (danxuliu@gmail.com)
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('OC.Share.ShareDialogLinkShareView', function () {
|
||||
|
||||
var configModel;
|
||||
var shareModel;
|
||||
var view;
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
var fileInfoModel = new OCA.Files.FileInfoModel({
|
||||
id: 123,
|
||||
name: 'shared_file_name.txt',
|
||||
path: '/subdir',
|
||||
size: 100,
|
||||
mimetype: 'text/plain',
|
||||
permissions: OC.PERMISSION_ALL,
|
||||
sharePermissions: OC.PERMISSION_ALL
|
||||
});
|
||||
|
||||
var attributes = {
|
||||
itemType: fileInfoModel.isDirectory() ? 'folder' : 'file',
|
||||
itemSource: fileInfoModel.get('id'),
|
||||
possiblePermissions: OC.PERMISSION_ALL,
|
||||
permissions: OC.PERMISSION_ALL
|
||||
};
|
||||
|
||||
configModel = new OC.Share.ShareConfigModel({
|
||||
enforcePasswordForPublicLink: false,
|
||||
isResharingAllowed: true,
|
||||
isDefaultExpireDateEnabled: false,
|
||||
isDefaultExpireDateEnforced: false,
|
||||
defaultExpireDate: 7
|
||||
});
|
||||
|
||||
sinon.stub(configModel, 'isShareWithLinkAllowed');
|
||||
|
||||
shareModel = new OC.Share.ShareItemModel(attributes, {
|
||||
configModel: configModel,
|
||||
fileInfoModel: fileInfoModel
|
||||
});
|
||||
|
||||
view = new OC.Share.ShareDialogLinkShareView({
|
||||
configModel: configModel,
|
||||
model: shareModel
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view.remove();
|
||||
configModel.isShareWithLinkAllowed.restore();
|
||||
});
|
||||
|
||||
describe('hide download', function () {
|
||||
|
||||
var $hideDownloadCheckbox;
|
||||
var $workingIcon;
|
||||
|
||||
beforeEach(function () {
|
||||
// Needed to render the view
|
||||
configModel.isShareWithLinkAllowed.returns(true);
|
||||
|
||||
shareModel.set({
|
||||
linkShares: [{
|
||||
id: 123
|
||||
}]
|
||||
});
|
||||
view.render();
|
||||
|
||||
$hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox');
|
||||
$workingIcon = $hideDownloadCheckbox.prev('.icon-loading-small');
|
||||
|
||||
sinon.stub(shareModel, 'saveLinkShare');
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeTruthy();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
shareModel.saveLinkShare.restore();
|
||||
});
|
||||
|
||||
it('is shown if the share is a file', function() {
|
||||
expect($hideDownloadCheckbox.length).toBeTruthy();
|
||||
});
|
||||
|
||||
it('is not shown if the share is a folder', function() {
|
||||
shareModel.fileInfoModel.set('mimetype', 'httpd/unix-directory');
|
||||
|
||||
// Setting the item type also triggers the rendering
|
||||
shareModel.set({
|
||||
itemType: 'folder'
|
||||
});
|
||||
|
||||
$hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox');
|
||||
|
||||
expect($hideDownloadCheckbox.length).toBeTruthy();
|
||||
});
|
||||
|
||||
it('checkbox is checked when the setting is enabled', function () {
|
||||
shareModel.set({
|
||||
linkShares: [{
|
||||
id: 123,
|
||||
hideDownload: true
|
||||
}]
|
||||
});
|
||||
view.render();
|
||||
|
||||
$hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox');
|
||||
|
||||
expect($hideDownloadCheckbox.is(':checked')).toEqual(true);
|
||||
});
|
||||
|
||||
it('checkbox is not checked when the setting is disabled', function () {
|
||||
expect($hideDownloadCheckbox.is(':checked')).toEqual(false);
|
||||
});
|
||||
|
||||
it('enables the setting if clicked when unchecked', function () {
|
||||
// Simulate the click by checking the checkbox and then triggering
|
||||
// the "change" event.
|
||||
$hideDownloadCheckbox.prop('checked', true);
|
||||
$hideDownloadCheckbox.change();
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeFalsy();
|
||||
expect(shareModel.saveLinkShare.withArgs({ hideDownload: true, cid: 123 }).calledOnce).toBeTruthy();
|
||||
});
|
||||
|
||||
it('disables the setting if clicked when checked', function () {
|
||||
shareModel.set({
|
||||
linkShares: [{
|
||||
id: 123,
|
||||
hideDownload: true
|
||||
}]
|
||||
});
|
||||
view.render();
|
||||
|
||||
$hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox');
|
||||
$workingIcon = $hideDownloadCheckbox.prev('.icon-loading-small');
|
||||
|
||||
// Simulate the click by unchecking the checkbox and then triggering
|
||||
// the "change" event.
|
||||
$hideDownloadCheckbox.prop('checked', false);
|
||||
$hideDownloadCheckbox.change();
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeFalsy();
|
||||
expect(shareModel.saveLinkShare.withArgs({ hideDownload: false, cid: 123 }).calledOnce).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('onPasswordEntered', function () {
|
||||
|
||||
var $passwordText;
|
||||
var $workingIcon;
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
// Needed to render the view
|
||||
configModel.isShareWithLinkAllowed.returns(true);
|
||||
|
||||
shareModel.set({
|
||||
linkShares: [{
|
||||
id: 123,
|
||||
password: 'password'
|
||||
}]
|
||||
});
|
||||
view.render();
|
||||
|
||||
$passwordText = view.$el.find('.linkPassText');
|
||||
$workingIcon = view.$el.find('.linkPassMenu .icon-loading-small');
|
||||
|
||||
sinon.stub(shareModel, 'saveLinkShare');
|
||||
|
||||
expect($passwordText.hasClass('hidden')).toBeFalsy();
|
||||
expect($workingIcon.hasClass('hidden')).toBeTruthy();
|
||||
|
||||
$passwordText.val('myPassword');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
shareModel.saveLinkShare.restore();
|
||||
});
|
||||
|
||||
it('shows the working icon when called', function () {
|
||||
view.onPasswordEntered({target: view.$el.find('.linkPassText')});
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeFalsy();
|
||||
expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword', cid: 123 }).calledOnce).toBeTruthy();
|
||||
});
|
||||
|
||||
it('hides the working icon when saving the password succeeds', function () {
|
||||
view.onPasswordEntered({target: view.$el.find('.linkPassText')});
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeFalsy();
|
||||
expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword', cid: 123 }).calledOnce).toBeTruthy();
|
||||
|
||||
shareModel.saveLinkShare.yieldTo("complete", [shareModel]);
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('hides the working icon when saving the password fails', function () {
|
||||
view.onPasswordEntered({target: view.$el.find('.linkPassText')});
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeFalsy();
|
||||
expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword', cid: 123 }).calledOnce).toBeTruthy();
|
||||
|
||||
shareModel.saveLinkShare.yieldTo("complete", [shareModel]);
|
||||
shareModel.saveLinkShare.yieldTo("error", [shareModel, "The error message"]);
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('protect password by Talk', function () {
|
||||
|
||||
var $passwordByTalkCheckbox;
|
||||
var $workingIcon;
|
||||
|
||||
beforeEach(function () {
|
||||
// Needed to render the view
|
||||
configModel.isShareWithLinkAllowed.returns(true);
|
||||
|
||||
// "Enable" Talk
|
||||
OC.appswebroots['spreed'] = OC.getRootPath() + '/apps/files/';
|
||||
|
||||
shareModel.set({
|
||||
linkShares: [{
|
||||
id: 123,
|
||||
password: 'password'
|
||||
}]
|
||||
});
|
||||
view.render();
|
||||
|
||||
$passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
|
||||
$workingIcon = $passwordByTalkCheckbox.prev('.icon-loading-small');
|
||||
|
||||
sinon.stub(shareModel, 'saveLinkShare');
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeTruthy();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
shareModel.saveLinkShare.restore();
|
||||
});
|
||||
|
||||
it('is shown if Talk is enabled and there is a password set', function() {
|
||||
expect($passwordByTalkCheckbox.length).toBeTruthy();
|
||||
});
|
||||
|
||||
it('is not shown if Talk is enabled but there is no password set', function() {
|
||||
// Changing the password value also triggers the rendering
|
||||
shareModel.set({
|
||||
linkShares: [{
|
||||
id: 123
|
||||
}]
|
||||
});
|
||||
|
||||
$passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
|
||||
|
||||
expect($passwordByTalkCheckbox.length).toBeFalsy();
|
||||
});
|
||||
|
||||
it('is not shown if there is a password set but Talk is not enabled', function() {
|
||||
// "Disable" Talk
|
||||
delete OC.appswebroots['spreed'];
|
||||
|
||||
view.render();
|
||||
|
||||
$passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
|
||||
|
||||
expect($passwordByTalkCheckbox.length).toBeFalsy();
|
||||
});
|
||||
|
||||
it('checkbox is checked when the setting is enabled', function () {
|
||||
shareModel.set({
|
||||
linkShares: [{
|
||||
id: 123,
|
||||
password: 'password',
|
||||
sendPasswordByTalk: true
|
||||
}]
|
||||
});
|
||||
view.render();
|
||||
|
||||
$passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
|
||||
|
||||
expect($passwordByTalkCheckbox.is(':checked')).toEqual(true);
|
||||
});
|
||||
|
||||
it('checkbox is not checked when the setting is disabled', function () {
|
||||
expect($passwordByTalkCheckbox.is(':checked')).toEqual(false);
|
||||
});
|
||||
|
||||
it('enables the setting if clicked when unchecked', function () {
|
||||
// Simulate the click by checking the checkbox and then triggering
|
||||
// the "change" event.
|
||||
$passwordByTalkCheckbox.prop('checked', true);
|
||||
$passwordByTalkCheckbox.change();
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeFalsy();
|
||||
expect(shareModel.saveLinkShare.withArgs({ sendPasswordByTalk: true, cid: 123 }).calledOnce).toBeTruthy();
|
||||
});
|
||||
|
||||
it('disables the setting if clicked when checked', function () {
|
||||
shareModel.set({
|
||||
linkShares: [{
|
||||
id: 123,
|
||||
password: 'password',
|
||||
sendPasswordByTalk: true
|
||||
}]
|
||||
});
|
||||
view.render();
|
||||
|
||||
$passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
|
||||
$workingIcon = $passwordByTalkCheckbox.prev('.icon-loading-small');
|
||||
|
||||
// Simulate the click by unchecking the checkbox and then triggering
|
||||
// the "change" event.
|
||||
$passwordByTalkCheckbox.prop('checked', false);
|
||||
$passwordByTalkCheckbox.change();
|
||||
|
||||
expect($workingIcon.hasClass('hidden')).toBeFalsy();
|
||||
expect(shareModel.saveLinkShare.withArgs({ sendPasswordByTalk: false, cid: 123 }).calledOnce).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
|
@ -1,242 +0,0 @@
|
|||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Tom Needham
|
||||
* @copyright 2015 Tom Needham <tom@owncloud.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('OC.Share.ShareDialogShareeListView', function () {
|
||||
|
||||
var oldCurrentUser;
|
||||
var fileInfoModel;
|
||||
var configModel;
|
||||
var shareModel;
|
||||
var listView;
|
||||
var updateShareStub;
|
||||
|
||||
beforeEach(function () {
|
||||
/* jshint camelcase:false */
|
||||
oldAppConfig = _.extend({}, OC.appConfig.core);
|
||||
OC.appConfig.core.enforcePasswordForPublicLink = false;
|
||||
|
||||
fileInfoModel = new OCA.Files.FileInfoModel({
|
||||
id: 123,
|
||||
name: 'shared_file_name.txt',
|
||||
path: '/subdir',
|
||||
size: 100,
|
||||
mimetype: 'text/plain',
|
||||
permissions: 31,
|
||||
sharePermissions: 31
|
||||
});
|
||||
|
||||
var attributes = {
|
||||
itemType: fileInfoModel.isDirectory() ? 'folder' : 'file',
|
||||
itemSource: fileInfoModel.get('id'),
|
||||
possiblePermissions: 31,
|
||||
permissions: 31
|
||||
};
|
||||
|
||||
shareModel = new OC.Share.ShareItemModel(attributes, {
|
||||
configModel: configModel,
|
||||
fileInfoModel: fileInfoModel
|
||||
});
|
||||
|
||||
configModel = new OC.Share.ShareConfigModel({
|
||||
enforcePasswordForPublicLink: false,
|
||||
isResharingAllowed: true,
|
||||
isDefaultExpireDateEnabled: false,
|
||||
isDefaultExpireDateEnforced: false,
|
||||
defaultExpireDate: 7
|
||||
});
|
||||
|
||||
listView = new OC.Share.ShareDialogShareeListView({
|
||||
configModel: configModel,
|
||||
model: shareModel
|
||||
});
|
||||
|
||||
// required for proper event propagation when simulating clicks in some cases (jquery bugs)
|
||||
$('#testArea').append(listView.$el);
|
||||
|
||||
shareModel.set({
|
||||
linkShares: []
|
||||
});
|
||||
|
||||
oldCurrentUser = OC.currentUser;
|
||||
OC.currentUser = 'user0';
|
||||
updateShareStub = sinon.stub(OC.Share.ShareItemModel.prototype, 'updateShare');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
OC.currentUser = oldCurrentUser;
|
||||
/* jshint camelcase:false */
|
||||
OC.appConfig.core = oldAppConfig;
|
||||
listView.remove();
|
||||
updateShareStub.restore();
|
||||
});
|
||||
|
||||
describe('Sets correct initial checkbox state', function () {
|
||||
|
||||
it('marks edit box as unchecked for file shares without edit permissions', function () {
|
||||
shareModel.set('shares', [{
|
||||
id: 100,
|
||||
item_source: 123,
|
||||
permissions: 1,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user1',
|
||||
share_with_displayname: 'User One',
|
||||
uid_owner: OC.getCurrentUser().uid,
|
||||
itemType: 'file'
|
||||
}]);
|
||||
listView.render();
|
||||
expect(listView.$el.find("input[name='edit']").is(':not(:checked)')).toEqual(true);
|
||||
});
|
||||
|
||||
it('marks edit box as checked for file shares', function () {
|
||||
shareModel.set('shares', [{
|
||||
id: 100,
|
||||
item_source: 123,
|
||||
permissions: 1 | OC.PERMISSION_UPDATE,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user1',
|
||||
share_with_displayname: 'User One',
|
||||
uid_owner: OC.getCurrentUser().uid,
|
||||
itemType: 'file'
|
||||
}]);
|
||||
listView.render();
|
||||
expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true);
|
||||
});
|
||||
|
||||
it('marks edit box as indeterminate when only some permissions are given', function () {
|
||||
shareModel.set('shares', [{
|
||||
id: 100,
|
||||
item_source: 123,
|
||||
permissions: 1 | OC.PERMISSION_UPDATE,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user1',
|
||||
share_with_displayname: 'User One',
|
||||
uid_owner: OC.getCurrentUser().uid,
|
||||
itemType: 'folder'
|
||||
}]);
|
||||
shareModel.set('itemType', 'folder');
|
||||
listView.render();
|
||||
expect(listView.$el.find("input[name='edit']").is(':indeterminate')).toEqual(true);
|
||||
});
|
||||
|
||||
it('marks edit box as indeterminate when only some permissions are given for sharee with special characters', function () {
|
||||
shareModel.set('shares', [{
|
||||
id: 100,
|
||||
item_source: 123,
|
||||
permissions: 1 | OC.PERMISSION_UPDATE,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user _.@-\'',
|
||||
share_with_displayname: 'User One',
|
||||
uid_owner: OC.getCurrentUser().uid,
|
||||
itemType: 'folder'
|
||||
}]);
|
||||
shareModel.set('itemType', 'folder');
|
||||
listView.render();
|
||||
expect(listView.$el.find("input[name='edit']").is(':indeterminate')).toEqual(true);
|
||||
});
|
||||
|
||||
it('Checks edit box when all permissions are given', function () {
|
||||
shareModel.set('shares', [{
|
||||
id: 100,
|
||||
item_source: 123,
|
||||
permissions: 1 | OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user1',
|
||||
share_with_displayname: 'User One',
|
||||
uid_owner: OC.getCurrentUser().uid,
|
||||
itemType: 'folder'
|
||||
}]);
|
||||
shareModel.set('itemType', 'folder');
|
||||
listView.render();
|
||||
expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true);
|
||||
});
|
||||
|
||||
it('Checks edit box when all permissions are given for sharee with special characters', function () {
|
||||
shareModel.set('shares', [{
|
||||
id: 100,
|
||||
item_source: 123,
|
||||
permissions: 1 | OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user _.@-\'',
|
||||
share_with_displayname: 'User One',
|
||||
uid_owner: OC.getCurrentUser().uid,
|
||||
itemType: 'folder'
|
||||
}]);
|
||||
shareModel.set('itemType', 'folder');
|
||||
listView.render();
|
||||
expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true);
|
||||
});
|
||||
});
|
||||
describe('Manages checkbox events correctly', function () {
|
||||
it('Checks cruds boxes when edit box checked', function () {
|
||||
shareModel.set('shares', [{
|
||||
id: 100,
|
||||
item_source: 123,
|
||||
permissions: 1,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user1',
|
||||
share_with_displayname: 'User One',
|
||||
uid_owner: OC.getCurrentUser().uid,
|
||||
}]);
|
||||
shareModel.set('itemType', 'folder');
|
||||
listView.render();
|
||||
listView.$el.find("input[name='edit']").click();
|
||||
expect(listView.$el.find("input[name='update']").is(':checked')).toEqual(true);
|
||||
expect(updateShareStub.calledOnce).toEqual(true);
|
||||
});
|
||||
|
||||
it('marks edit box as indeterminate when some of create/update/delete are checked', function () {
|
||||
shareModel.set('shares', [{
|
||||
id: 100,
|
||||
item_source: 123,
|
||||
permissions: 1,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user1',
|
||||
share_with_displayname: 'User One',
|
||||
uid_owner: OC.getCurrentUser().uid,
|
||||
itemType: 'folder'
|
||||
}]);
|
||||
shareModel.set('itemType', 'folder');
|
||||
listView.render();
|
||||
listView.$el.find("input[name='update']").click();
|
||||
expect(listView.$el.find("input[name='edit']").is(':indeterminate')).toEqual(true);
|
||||
expect(updateShareStub.calledOnce).toEqual(true);
|
||||
});
|
||||
|
||||
it('Checks edit box when all of create/update/delete are checked', function () {
|
||||
shareModel.set('shares', [{
|
||||
id: 100,
|
||||
item_source: 123,
|
||||
permissions: 1 | OC.PERMISSION_CREATE | OC.PERMISSION_DELETE,
|
||||
share_type: OC.Share.SHARE_TYPE_USER,
|
||||
share_with: 'user1',
|
||||
share_with_displayname: 'User One',
|
||||
uid_owner: OC.getCurrentUser().uid,
|
||||
itemType: 'folder'
|
||||
}]);
|
||||
shareModel.set('itemType', 'folder');
|
||||
listView.render();
|
||||
listView.$el.find("input[name='update']").click();
|
||||
expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true);
|
||||
expect(updateShareStub.calledOnce).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue