aboutsummaryrefslogtreecommitdiffstats
path: root/core/js/tests/specs
diff options
context:
space:
mode:
Diffstat (limited to 'core/js/tests/specs')
-rw-r--r--core/js/tests/specs/appsSpec.js48
-rw-r--r--core/js/tests/specs/coreSpec.js1184
-rw-r--r--core/js/tests/specs/files/clientSpec.js118
-rw-r--r--core/js/tests/specs/jquery.avatarSpec.js175
-rw-r--r--core/js/tests/specs/jquery.contactsmenuSpec.js235
-rw-r--r--core/js/tests/specs/jquery.placeholderSpec.js38
-rw-r--r--core/js/tests/specs/l10nSpec.js98
-rw-r--r--core/js/tests/specs/mimeTypeSpec.js38
-rw-r--r--core/js/tests/specs/oc-backbone-webdavSpec.js111
-rw-r--r--core/js/tests/specs/public/commentsSpec.js38
-rw-r--r--core/js/tests/specs/setupchecksSpec.js634
-rw-r--r--core/js/tests/specs/shareSpec.js243
-rw-r--r--core/js/tests/specs/sharedialogshareelistview.js158
-rw-r--r--core/js/tests/specs/sharedialogviewSpec.js1064
-rw-r--r--core/js/tests/specs/shareitemmodelSpec.js828
-rw-r--r--core/js/tests/specs/systemtags/systemtagsSpec.js45
-rw-r--r--core/js/tests/specs/systemtags/systemtagscollectionSpec.js22
-rw-r--r--core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js185
18 files changed, 1461 insertions, 3801 deletions
diff --git a/core/js/tests/specs/appsSpec.js b/core/js/tests/specs/appsSpec.js
deleted file mode 100644
index 536d41c7f10..00000000000
--- a/core/js/tests/specs/appsSpec.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2015 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('Apps base tests', function() {
- describe('Sidebar utility functions', function() {
- beforeEach(function() {
- $('#testArea').append('<div id="app-content">Content</div><div id="app-sidebar">The sidebar</div>');
- });
- it('shows sidebar', function() {
- var $el = $('#app-sidebar');
- OC.Apps.showAppSidebar();
- expect($el.hasClass('disappear')).toEqual(false);
- });
- it('hides sidebar', function() {
- var $el = $('#app-sidebar');
- OC.Apps.showAppSidebar();
- OC.Apps.hideAppSidebar();
- expect($el.hasClass('disappear')).toEqual(true);
- });
- it('triggers appresize event when visibility changed', function() {
- var eventStub = sinon.stub();
- $('#app-content').on('appresized', eventStub);
- OC.Apps.showAppSidebar();
- expect(eventStub.calledOnce).toEqual(true);
- OC.Apps.hideAppSidebar();
- expect(eventStub.calledTwice).toEqual(true);
- });
- });
-});
-
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index f18ecbc1a44..3cbd7623a47 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -1,25 +1,19 @@
/**
-* 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/>.
-*
-*/
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2014 ownCloud Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
describe('Core base tests', function() {
+ var debounceStub
+ beforeEach(function() {
+ debounceStub = sinon.stub(_, 'debounce').callsFake(function(callback) {
+ return function() {
+ // defer instead of debounce, to make it work with clock
+ _.defer(callback);
+ };
+ });
+ });
afterEach(function() {
// many tests call window.initCore so need to unregister global events
// ideally in the future we'll need a window.unloadCore() function
@@ -28,173 +22,21 @@ describe('Core base tests', function() {
$(document).off('beforeunload.main');
OC._userIsNavigatingAway = false;
OC._reloadCalled = false;
+ debounceStub.restore();
});
describe('Base values', function() {
it('Sets webroots', function() {
- expect(OC.webroot).toBeDefined();
- expect(OC.appswebroots).toBeDefined();
- });
- });
- describe('basename', function() {
- it('Returns the nothing if no file name given', function() {
- expect(OC.basename('')).toEqual('');
- });
- it('Returns the nothing if dir is root', function() {
- expect(OC.basename('/')).toEqual('');
- });
- it('Returns the same name if no path given', function() {
- expect(OC.basename('some name.txt')).toEqual('some name.txt');
- });
- it('Returns the base name if root path given', function() {
- expect(OC.basename('/some name.txt')).toEqual('some name.txt');
- });
- it('Returns the base name if double root path given', function() {
- expect(OC.basename('//some name.txt')).toEqual('some name.txt');
- });
- it('Returns the base name if subdir given without root', function() {
- expect(OC.basename('subdir/some name.txt')).toEqual('some name.txt');
- });
- it('Returns the base name if subdir given with root', function() {
- expect(OC.basename('/subdir/some name.txt')).toEqual('some name.txt');
- });
- it('Returns the base name if subdir given with double root', function() {
- expect(OC.basename('//subdir/some name.txt')).toEqual('some name.txt');
- });
- it('Returns the base name if subdir has dot', function() {
- expect(OC.basename('/subdir.dat/some name.txt')).toEqual('some name.txt');
- });
- it('Returns dot if file name is dot', function() {
- expect(OC.basename('/subdir/.')).toEqual('.');
- });
- // TODO: fix the source to make it work like PHP's basename
- it('Returns the dir itself if no file name given', function() {
- // TODO: fix the source to make it work like PHP's dirname
- // expect(OC.basename('subdir/')).toEqual('subdir');
- expect(OC.basename('subdir/')).toEqual('');
- });
- it('Returns the dir itself if no file name given with root', function() {
- // TODO: fix the source to make it work like PHP's dirname
- // expect(OC.basename('/subdir/')).toEqual('subdir');
- expect(OC.basename('/subdir/')).toEqual('');
- });
- });
- describe('dirname', function() {
- it('Returns the nothing if no file name given', function() {
- expect(OC.dirname('')).toEqual('');
- });
- it('Returns the root if dir is root', function() {
- // TODO: fix the source to make it work like PHP's dirname
- // expect(OC.dirname('/')).toEqual('/');
- expect(OC.dirname('/')).toEqual('');
- });
- it('Returns the root if dir is double root', function() {
- // TODO: fix the source to make it work like PHP's dirname
- // expect(OC.dirname('//')).toEqual('/');
- expect(OC.dirname('//')).toEqual('/'); // oh no...
- });
- it('Returns dot if dir is dot', function() {
- expect(OC.dirname('.')).toEqual('.');
- });
- it('Returns dot if no root given', function() {
- // TODO: fix the source to make it work like PHP's dirname
- // expect(OC.dirname('some dir')).toEqual('.');
- expect(OC.dirname('some dir')).toEqual('some dir'); // oh no...
- });
- it('Returns the dir name if file name and root path given', function() {
- // TODO: fix the source to make it work like PHP's dirname
- // expect(OC.dirname('/some name.txt')).toEqual('/');
- expect(OC.dirname('/some name.txt')).toEqual('');
- });
- it('Returns the dir name if double root path given', function() {
- expect(OC.dirname('//some name.txt')).toEqual('/'); // how lucky...
- });
- it('Returns the dir name if subdir given without root', function() {
- expect(OC.dirname('subdir/some name.txt')).toEqual('subdir');
- });
- it('Returns the dir name if subdir given with root', function() {
- expect(OC.dirname('/subdir/some name.txt')).toEqual('/subdir');
- });
- it('Returns the dir name if subdir given with double root', function() {
- // TODO: fix the source to make it work like PHP's dirname
- // expect(OC.dirname('//subdir/some name.txt')).toEqual('/subdir');
- expect(OC.dirname('//subdir/some name.txt')).toEqual('//subdir'); // oh...
- });
- it('Returns the dir name if subdir has dot', function() {
- expect(OC.dirname('/subdir.dat/some name.txt')).toEqual('/subdir.dat');
- });
- it('Returns the dir name if file name is dot', function() {
- expect(OC.dirname('/subdir/.')).toEqual('/subdir');
- });
- it('Returns the dir name if no file name given', function() {
- expect(OC.dirname('subdir/')).toEqual('subdir');
- });
- it('Returns the dir name if no file name given with root', function() {
- expect(OC.dirname('/subdir/')).toEqual('/subdir');
- });
- });
- describe('escapeHTML', function() {
- it('Returns nothing if no string was given', function() {
- expect(escapeHTML('')).toEqual('');
- });
- it('Returns a sanitized string if a string containing HTML is given', function() {
- expect(escapeHTML('There needs to be a <script>alert(\"Unit\" + \'test\')</script> for it!')).toEqual('There needs to be a &lt;script&gt;alert(&quot;Unit&quot; + &#039;test&#039;)&lt;/script&gt; for it!');
- });
- it('Returns the string without modification if no potentially dangerous character is passed.', function() {
- expect(escapeHTML('This is a good string without HTML.')).toEqual('This is a good string without HTML.');
- });
- });
- describe('joinPaths', function() {
- it('returns empty string with no or empty arguments', function() {
- expect(OC.joinPaths()).toEqual('');
- expect(OC.joinPaths('')).toEqual('');
- expect(OC.joinPaths('', '')).toEqual('');
- });
- it('returns joined path sections', function() {
- expect(OC.joinPaths('abc')).toEqual('abc');
- expect(OC.joinPaths('abc', 'def')).toEqual('abc/def');
- expect(OC.joinPaths('abc', 'def', 'ghi')).toEqual('abc/def/ghi');
- });
- it('keeps leading slashes', function() {
- expect(OC.joinPaths('/abc')).toEqual('/abc');
- expect(OC.joinPaths('/abc', '')).toEqual('/abc');
- expect(OC.joinPaths('', '/abc')).toEqual('/abc');
- expect(OC.joinPaths('/abc', 'def')).toEqual('/abc/def');
- expect(OC.joinPaths('/abc', 'def', 'ghi')).toEqual('/abc/def/ghi');
- });
- it('keeps trailing slashes', function() {
- expect(OC.joinPaths('', 'abc/')).toEqual('abc/');
- expect(OC.joinPaths('abc/')).toEqual('abc/');
- expect(OC.joinPaths('abc/', '')).toEqual('abc/');
- expect(OC.joinPaths('abc', 'def/')).toEqual('abc/def/');
- expect(OC.joinPaths('abc', 'def', 'ghi/')).toEqual('abc/def/ghi/');
- });
- it('splits paths in specified strings and discards extra slashes', function() {
- expect(OC.joinPaths('//abc//')).toEqual('/abc/');
- expect(OC.joinPaths('//abc//def//')).toEqual('/abc/def/');
- expect(OC.joinPaths('//abc//', '//def//')).toEqual('/abc/def/');
- expect(OC.joinPaths('//abc//', '//def//', '//ghi//')).toEqual('/abc/def/ghi/');
- expect(OC.joinPaths('//abc//def//', '//ghi//jkl/mno/', '//pqr//'))
- .toEqual('/abc/def/ghi/jkl/mno/pqr/');
- expect(OC.joinPaths('/abc', '/def')).toEqual('/abc/def');
- expect(OC.joinPaths('/abc/', '/def')).toEqual('/abc/def');
- expect(OC.joinPaths('/abc/', 'def')).toEqual('/abc/def');
- });
- it('discards empty sections', function() {
- expect(OC.joinPaths('abc', '', 'def')).toEqual('abc/def');
- });
- it('returns root if only slashes', function() {
- expect(OC.joinPaths('//')).toEqual('/');
- expect(OC.joinPaths('/', '/')).toEqual('/');
- expect(OC.joinPaths('/', '//', '/')).toEqual('/');
+ expect(OC.getRootPath()).toBeDefined();
+ expect(window._oc_appswebroots).toBeDefined();
});
});
describe('filePath', function() {
beforeEach(function() {
- OC.webroot = 'http://localhost';
- OC.appswebroots['files'] = OC.webroot + '/apps3/files';
+ window._oc_webroot = 'http://localhost';
+ window._oc_appswebroots.files = OC.getRootPath() + '/apps3/files';
});
afterEach(function() {
- delete OC.appswebroots['files'];
+ delete window._oc_appswebroots.files;
});
it('Uses a direct link for css and images,' , function() {
@@ -210,43 +52,33 @@ describe('Core base tests', function() {
});
describe('Link functions', function() {
var TESTAPP = 'testapp';
- var TESTAPP_ROOT = OC.webroot + '/appsx/testapp';
+ var TESTAPP_ROOT = OC.getRootPath() + '/appsx/testapp';
beforeEach(function() {
- OC.appswebroots[TESTAPP] = TESTAPP_ROOT;
+ window._oc_appswebroots[TESTAPP] = TESTAPP_ROOT;
});
afterEach(function() {
// restore original array
- delete OC.appswebroots[TESTAPP];
+ delete window._oc_appswebroots[TESTAPP];
});
it('Generates correct links for core apps', function() {
- expect(OC.linkTo('core', 'somefile.php')).toEqual(OC.webroot + '/core/somefile.php');
- expect(OC.linkTo('admin', 'somefile.php')).toEqual(OC.webroot + '/admin/somefile.php');
+ expect(OC.linkTo('core', 'somefile.php')).toEqual(OC.getRootPath() + '/core/somefile.php');
+ expect(OC.linkTo('admin', 'somefile.php')).toEqual(OC.getRootPath() + '/admin/somefile.php');
});
it('Generates correct links for regular apps', function() {
- expect(OC.linkTo(TESTAPP, 'somefile.php')).toEqual(OC.webroot + '/index.php/apps/' + TESTAPP + '/somefile.php');
+ expect(OC.linkTo(TESTAPP, 'somefile.php')).toEqual(OC.getRootPath() + '/index.php/apps/' + TESTAPP + '/somefile.php');
});
it('Generates correct remote links', function() {
- expect(OC.linkToRemote('webdav')).toEqual(window.location.protocol + '//' + window.location.host + OC.webroot + '/remote.php/webdav');
+ expect(OC.linkToRemote('webdav')).toEqual(window.location.protocol + '//' + window.location.host + OC.getRootPath() + '/remote.php/webdav');
});
describe('Images', function() {
it('Generates image path with given extension', function() {
- var svgSupportStub = sinon.stub(OC.Util, 'hasSVGSupport', function() { return true; });
- expect(OC.imagePath('core', 'somefile.jpg')).toEqual(OC.webroot + '/core/img/somefile.jpg');
+ expect(OC.imagePath('core', 'somefile.jpg')).toEqual(OC.getRootPath() + '/core/img/somefile.jpg');
expect(OC.imagePath(TESTAPP, 'somefile.jpg')).toEqual(TESTAPP_ROOT + '/img/somefile.jpg');
- svgSupportStub.restore();
});
- it('Generates image path with svg extension when svg support exists', function() {
- var svgSupportStub = sinon.stub(OC.Util, 'hasSVGSupport', function() { return true; });
- expect(OC.imagePath('core', 'somefile')).toEqual(OC.webroot + '/core/img/somefile.svg');
+ it('Generates image path with svg extension', function() {
+ expect(OC.imagePath('core', 'somefile')).toEqual(OC.getRootPath() + '/core/img/somefile.svg');
expect(OC.imagePath(TESTAPP, 'somefile')).toEqual(TESTAPP_ROOT + '/img/somefile.svg');
- svgSupportStub.restore();
- });
- it('Generates image path with png ext when svg support is not available', function() {
- var svgSupportStub = sinon.stub(OC.Util, 'hasSVGSupport', function() { return false; });
- expect(OC.imagePath('core', 'somefile')).toEqual(OC.webroot + '/core/img/somefile.png');
- expect(OC.imagePath(TESTAPP, 'somefile')).toEqual(TESTAPP_ROOT + '/img/somefile.png');
- svgSupportStub.restore();
});
});
});
@@ -287,96 +119,6 @@ describe('Core base tests', function() {
})).toEqual('number=123');
});
});
- describe('Session heartbeat', function() {
- var clock,
- oldConfig,
- routeStub,
- counter;
-
- beforeEach(function() {
- clock = sinon.useFakeTimers();
- oldConfig = window.oc_config;
- routeStub = sinon.stub(OC, 'generateUrl').returns('/heartbeat');
- counter = 0;
-
- fakeServer.autoRespond = true;
- fakeServer.autoRespondAfter = 0;
- fakeServer.respondWith(/\/heartbeat/, function(xhr) {
- counter++;
- xhr.respond(200, {'Content-Type': 'application/json'}, '{}');
- });
- });
- afterEach(function() {
- clock.restore();
- /* jshint camelcase: false */
- window.oc_config = oldConfig;
- routeStub.restore();
- $(document).off('ajaxError');
- });
- it('sends heartbeat half the session lifetime when heartbeat enabled', function() {
- /* jshint camelcase: false */
- window.oc_config = {
- session_keepalive: true,
- session_lifetime: 300
- };
- window.initCore();
- expect(routeStub.calledWith('/heartbeat')).toEqual(true);
-
- expect(counter).toEqual(0);
-
- // less than half, still nothing
- clock.tick(100 * 1000);
- expect(counter).toEqual(0);
-
- // reach past half (160), one call
- clock.tick(55 * 1000);
- expect(counter).toEqual(1);
-
- // almost there to the next, still one
- clock.tick(140 * 1000);
- expect(counter).toEqual(1);
-
- // past it, second call
- clock.tick(20 * 1000);
- expect(counter).toEqual(2);
- });
- it('does no send heartbeat when heartbeat disabled', function() {
- /* jshint camelcase: false */
- window.oc_config = {
- session_keepalive: false,
- session_lifetime: 300
- };
- window.initCore();
- expect(routeStub.notCalled).toEqual(true);
-
- expect(counter).toEqual(0);
-
- clock.tick(1000000);
-
- // still nothing
- expect(counter).toEqual(0);
- });
- it('limits the heartbeat between one minute and one day', function() {
- /* jshint camelcase: false */
- var setIntervalStub = sinon.stub(window, 'setInterval');
- window.oc_config = {
- session_keepalive: true,
- session_lifetime: 5
- };
- window.initCore();
- expect(setIntervalStub.getCall(0).args[1]).toEqual(60 * 1000);
- setIntervalStub.reset();
-
- window.oc_config = {
- session_keepalive: true,
- session_lifetime: 48 * 3600
- };
- window.initCore();
- expect(setIntervalStub.getCall(0).args[1]).toEqual(24 * 3600 * 1000);
-
- setIntervalStub.restore();
- });
- });
describe('Parse query string', function() {
it('Parses query string from full URL', function() {
var query = OC.parseQueryString('http://localhost/stuff.php?q=a&b=x');
@@ -445,117 +187,74 @@ describe('Core base tests', function() {
});
describe('Generate Url', function() {
it('returns absolute urls', function() {
- expect(OC.generateUrl('heartbeat')).toEqual(OC.webroot + '/index.php/heartbeat');
- expect(OC.generateUrl('/heartbeat')).toEqual(OC.webroot + '/index.php/heartbeat');
+ expect(OC.generateUrl('csrftoken')).toEqual(OC.getRootPath() + '/index.php/csrftoken');
+ expect(OC.generateUrl('/csrftoken')).toEqual(OC.getRootPath() + '/index.php/csrftoken');
});
it('substitutes parameters which are escaped by default', function() {
- expect(OC.generateUrl('apps/files/download/{file}', {file: '<">ImAnUnescapedString/!'})).toEqual(OC.webroot + '/index.php/apps/files/download/%3C%22%3EImAnUnescapedString%2F!');
+ expect(OC.generateUrl('apps/files/download/{file}', {file: '<">ImAnUnescapedString/!'})).toEqual(OC.getRootPath() + '/index.php/apps/files/download/%3C%22%3EImAnUnescapedString%2F!');
});
it('substitutes parameters which can also be unescaped via option flag', function() {
- expect(OC.generateUrl('apps/files/download/{file}', {file: 'subfolder/Welcome.txt'}, {escape: false})).toEqual(OC.webroot + '/index.php/apps/files/download/subfolder/Welcome.txt');
+ expect(OC.generateUrl('apps/files/download/{file}', {file: 'subfolder/Welcome.txt'}, {escape: false})).toEqual(OC.getRootPath() + '/index.php/apps/files/download/subfolder/Welcome.txt');
});
it('substitutes multiple parameters which are escaped by default', function() {
- expect(OC.generateUrl('apps/files/download/{file}/{id}', {file: '<">ImAnUnescapedString/!', id: 5})).toEqual(OC.webroot + '/index.php/apps/files/download/%3C%22%3EImAnUnescapedString%2F!/5');
+ expect(OC.generateUrl('apps/files/download/{file}/{id}', {file: '<">ImAnUnescapedString/!', id: 5})).toEqual(OC.getRootPath() + '/index.php/apps/files/download/%3C%22%3EImAnUnescapedString%2F!/5');
});
it('substitutes multiple parameters which can also be unescaped via option flag', function() {
- expect(OC.generateUrl('apps/files/download/{file}/{id}', {file: 'subfolder/Welcome.txt', id: 5}, {escape: false})).toEqual(OC.webroot + '/index.php/apps/files/download/subfolder/Welcome.txt/5');
+ expect(OC.generateUrl('apps/files/download/{file}/{id}', {file: 'subfolder/Welcome.txt', id: 5}, {escape: false})).toEqual(OC.getRootPath() + '/index.php/apps/files/download/subfolder/Welcome.txt/5');
});
it('doesnt error out with no params provided', function () {
- expect(OC.generateUrl('apps/files/download{file}')).toEqual(OC.webroot + '/index.php/apps/files/download%7Bfile%7D');
- });
- });
- describe('Main menu mobile toggle', function() {
- var clock;
- var $toggle;
- var $navigation;
-
- beforeEach(function() {
- clock = sinon.useFakeTimers();
- $('#testArea').append('<div id="header">' +
- '<a class="menutoggle header-appname-container" href="#">' +
- '<h1 class="header-appname"></h1>' +
- '<div class="icon-caret"></div>' +
- '</a>' +
- '</div>' +
- '<div id="navigation"></div>');
- $toggle = $('#header').find('.menutoggle');
- $navigation = $('#navigation');
- });
- afterEach(function() {
- clock.restore();
- $(document).off('ajaxError');
- });
- it('Sets up menu toggle', function() {
- window.initCore();
- expect($navigation.hasClass('menu')).toEqual(true);
- });
- it('Clicking menu toggle toggles navigation in', function() {
- window.initCore();
- $navigation.hide(); // normally done through media query triggered CSS
- expect($navigation.is(':visible')).toEqual(false);
- $toggle.click();
- clock.tick(1 * 1000);
- expect($navigation.is(':visible')).toEqual(true);
- $toggle.click();
- clock.tick(1 * 1000);
- expect($navigation.is(':visible')).toEqual(false);
- });
- });
- describe('SVG extension replacement', function() {
- var svgSupportStub;
-
- beforeEach(function() {
- svgSupportStub = sinon.stub(OC.Util, 'hasSVGSupport');
- });
- afterEach(function() {
- svgSupportStub.restore();
- });
- it('does not replace svg extension with png when SVG is supported', function() {
- svgSupportStub.returns(true);
- expect(
- OC.Util.replaceSVGIcon('/path/to/myicon.svg?someargs=1')
- ).toEqual(
- '/path/to/myicon.svg?someargs=1'
- );
- });
- it('replaces svg extension with png when SVG not supported', function() {
- svgSupportStub.returns(false);
- expect(
- OC.Util.replaceSVGIcon('/path/to/myicon.svg?someargs=1')
- ).toEqual(
- '/path/to/myicon.png?someargs=1'
- );
+ expect(OC.generateUrl('apps/files/download{file}')).toEqual(OC.getRootPath() + '/index.php/apps/files/download%7Bfile%7D');
});
});
describe('Util', function() {
- describe('humanFileSize', function() {
- it('renders file sizes with the correct unit', function() {
+ describe('computerFileSize', function() {
+ it('correctly parses file sizes from a human readable formated string', function() {
var data = [
- [0, '0 B'],
- ["0", '0 B'],
- ["A", 'NaN B'],
- [125, '125 B'],
- [128000, '125 KB'],
- [128000000, '122.1 MB'],
- [128000000000, '119.2 GB'],
- [128000000000000, '116.4 TB']
+ ['125', 125],
+ ['125.25', 125],
+ ['125.25B', 125],
+ ['125.25 B', 125],
+ ['0 B', 0],
+ ['99999999999999999999999999999999999999999999 B', 99999999999999999999999999999999999999999999],
+ ['0 MB', 0],
+ ['0 kB', 0],
+ ['0kB', 0],
+ ['125 B', 125],
+ ['125b', 125],
+ ['125 KB', 128000],
+ ['125kb', 128000],
+ ['122.1 MB', 128031130],
+ ['122.1mb', 128031130],
+ ['119.2 GB', 127990025421],
+ ['119.2gb', 127990025421],
+ ['116.4 TB', 127983153473126],
+ ['116.4tb', 127983153473126],
+ ['8776656778888777655.4tb', 9.650036181387265e+30],
+ [1234, null],
+ [-1234, null],
+ ['-1234 B', null],
+ ['B', null],
+ ['40/0', null],
+ ['40,30 kb', null],
+ [' 122.1 MB ', 128031130],
+ ['122.1 MB ', 128031130],
+ [' 122.1 MB ', 128031130],
+ [' 122.1 MB ', 128031130],
+ ['122.1 MB ', 128031130],
+ [' 125', 125],
+ [' 125 ', 125],
];
for (var i = 0; i < data.length; i++) {
- expect(OC.Util.humanFileSize(data[i][0])).toEqual(data[i][1]);
+ expect(OC.Util.computerFileSize(data[i][0])).toEqual(data[i][1]);
}
});
- it('renders file sizes with the correct unit for small sizes', function() {
- var data = [
- [0, '0 KB'],
- [125, '< 1 KB'],
- [128000, '125 KB'],
- [128000000, '122.1 MB'],
- [128000000000, '119.2 GB'],
- [128000000000000, '116.4 TB']
- ];
- for (var i = 0; i < data.length; i++) {
- expect(OC.Util.humanFileSize(data[i][0], true)).toEqual(data[i][1]);
- }
+ it('returns null if the parameter is not a string', function() {
+ expect(OC.Util.computerFileSize(NaN)).toEqual(null);
+ expect(OC.Util.computerFileSize(125)).toEqual(null);
+ });
+ it('returns null if the string is unparsable', function() {
+ expect(OC.Util.computerFileSize('')).toEqual(null);
+ expect(OC.Util.computerFileSize('foobar')).toEqual(null);
});
});
describe('stripTime', function() {
@@ -573,7 +272,7 @@ describe('Core base tests', function() {
// to make sure they run.
var cit = window.isPhantom?xit:it;
- // must provide the same results as \OC_Util::naturalSortCompare
+ // must provide the same results as \OCP\Util::naturalSortCompare
it('sorts alphabetically', function() {
var a = [
'def',
@@ -756,250 +455,693 @@ describe('Core base tests', function() {
});
});
describe('Notifications', function() {
- var showSpy;
var showHtmlSpy;
- var hideSpy;
var clock;
+ /**
+ * Returns the HTML or plain text of the given notification row.
+ *
+ * This is needed to ignore the close button that is added to the
+ * notification row after the text.
+ */
+ var getNotificationText = function($node) {
+ return $node.contents()[0].outerHTML ||
+ $node.contents()[0].nodeValue;
+ }
+
beforeEach(function() {
clock = sinon.useFakeTimers();
- showSpy = sinon.spy(OC.Notification, 'show');
- showHtmlSpy = sinon.spy(OC.Notification, 'showHtml');
- hideSpy = sinon.spy(OC.Notification, 'hide');
-
- $('#testArea').append('<div id="notification"></div>');
});
afterEach(function() {
- showSpy.restore();
- showHtmlSpy.restore();
- hideSpy.restore();
// jump past animations
clock.tick(10000);
clock.restore();
+ $('body .toastify').remove();
});
describe('showTemporary', function() {
it('shows a plain text notification with default timeout', function() {
- var $row = OC.Notification.showTemporary('My notification test');
-
- expect(showSpy.calledOnce).toEqual(true);
- expect(showSpy.firstCall.args[0]).toEqual('My notification test');
- expect(showSpy.firstCall.args[1]).toEqual({isHTML: false, timeout: 7});
+ OC.Notification.showTemporary('My notification test');
- expect($row).toBeDefined();
- expect($row.text()).toEqual('My notification test');
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
+ expect(getNotificationText($row)).toEqual('My notification test');
});
it('shows a HTML notification with default timeout', function() {
- var $row = OC.Notification.showTemporary('<a>My notification test</a>', { isHTML: true });
-
- expect(showSpy.notCalled).toEqual(true);
- expect(showHtmlSpy.calledOnce).toEqual(true);
- expect(showHtmlSpy.firstCall.args[0]).toEqual('<a>My notification test</a>');
- expect(showHtmlSpy.firstCall.args[1]).toEqual({isHTML: true, timeout: 7});
+ OC.Notification.showTemporary('<a>My notification test</a>', { isHTML: true });
- expect($row).toBeDefined();
- expect($row.text()).toEqual('My notification test');
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
+ expect(getNotificationText($row)).toEqual('<a>My notification test</a>');
});
it('hides itself after 7 seconds', function() {
- var $row = OC.Notification.showTemporary('');
+ OC.Notification.showTemporary('');
+
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
+
+ // travel in time +7000 milliseconds
+ clock.tick(7500);
+
+ $row = $('body .toastify');
+ expect($row.length).toEqual(0);
+ });
+ it('hides itself after a given time', function() {
+ OC.Notification.showTemporary('', {timeout: 10000});
+
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
// travel in time +7000 milliseconds
- clock.tick(7000);
+ clock.tick(7500);
+
+ $row = $('body .toastify');
+ expect($row.length).toEqual(1);
- expect(hideSpy.calledOnce).toEqual(true);
- expect(hideSpy.firstCall.args[0]).toEqual($row);
+ // travel in time another 4000 milliseconds
+ clock.tick(4000);
+
+ $row = $('body .toastify');
+ expect($row.length).toEqual(0);
});
});
describe('show', function() {
it('hides itself after a given time', function() {
- OC.Notification.show('', { timeout: 10 });
-
- // travel in time +9 seconds
- clock.tick(9000);
+ OC.Notification.show('', {timeout: 10000});
- expect(hideSpy.notCalled).toEqual(true);
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
- // travel in time +1 seconds
- clock.tick(1000);
+ clock.tick(11500);
- expect(hideSpy.calledOnce).toEqual(true);
+ $row = $('body .toastify');
+ expect($row.length).toEqual(0);
});
- it('does not hide itself after a given time if a timeout of 0 is defined', function() {
- OC.Notification.show('', { timeout: 0 });
+ it('does not hide itself if no timeout given to show', function() {
+ OC.Notification.show('');
+
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
// travel in time +1000 seconds
clock.tick(1000000);
- expect(hideSpy.notCalled).toEqual(true);
+ $row = $('body .toastify');
+ expect($row.length).toEqual(1);
+ });
+ });
+ describe('showHtml', function() {
+ it('hides itself after a given time', function() {
+ OC.Notification.showHtml('<p></p>', {timeout: 10000});
+
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
+
+ clock.tick(11500);
+
+ $row = $('body .toastify');
+ expect($row.length).toEqual(0);
});
it('does not hide itself if no timeout given to show', function() {
- OC.Notification.show('');
+ OC.Notification.showHtml('<p></p>');
+
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
// travel in time +1000 seconds
clock.tick(1000000);
- expect(hideSpy.notCalled).toEqual(true);
+ $row = $('body .toastify');
+ expect($row.length).toEqual(1);
});
});
- it('cumulates several notifications', function() {
- var $row1 = OC.Notification.showTemporary('One');
- var $row2 = OC.Notification.showTemporary('Two', {timeout: 2});
- var $row3 = OC.Notification.showTemporary('Three');
+ describe('hide', function() {
+ it('hides a temporary notification before its timeout expires', function() {
+ var hideCallback = sinon.spy();
- var $el = $('#notification');
- var $rows = $el.find('.row');
- expect($rows.length).toEqual(3);
+ var notification = OC.Notification.showTemporary('');
- expect($rows.eq(0).is($row1)).toEqual(true);
- expect($rows.eq(1).is($row2)).toEqual(true);
- expect($rows.eq(2).is($row3)).toEqual(true);
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
- clock.tick(3000);
+ OC.Notification.hide(notification, hideCallback);
- $rows = $el.find('.row');
- expect($rows.length).toEqual(2);
+ // Give time to the hide animation to finish
+ clock.tick(1000);
- expect($rows.eq(0).is($row1)).toEqual(true);
- expect($rows.eq(1).is($row3)).toEqual(true);
- });
- it('shows close button for error types', function() {
- var $row = OC.Notification.showTemporary('One');
- var $rowError = OC.Notification.showTemporary('Two', {type: 'error'});
- expect($row.find('.close').length).toEqual(0);
- expect($rowError.find('.close').length).toEqual(1);
+ $row = $('body .toastify');
+ expect($row.length).toEqual(0);
- // after clicking, row is gone
- $rowError.find('.close').click();
+ expect(hideCallback.calledOnce).toEqual(true);
+ });
+ it('hides a notification before its timeout expires', function() {
+ var hideCallback = sinon.spy();
- var $rows = $('#notification').find('.row');
- expect($rows.length).toEqual(1);
- expect($rows.eq(0).is($row)).toEqual(true);
- });
- it('fades out the last notification but not the other ones', function() {
- var fadeOutStub = sinon.stub($.fn, 'fadeOut');
- var $row1 = OC.Notification.show('One', {type: 'error'});
- var $row2 = OC.Notification.show('Two', {type: 'error'});
- OC.Notification.showTemporary('Three', {timeout: 2});
+ var notification = OC.Notification.show('', {timeout: 10000});
- var $el = $('#notification');
- var $rows = $el.find('.row');
- expect($rows.length).toEqual(3);
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
- clock.tick(3000);
+ OC.Notification.hide(notification, hideCallback);
- $rows = $el.find('.row');
- expect($rows.length).toEqual(2);
+ // Give time to the hide animation to finish
+ clock.tick(1000);
- $row1.find('.close').click();
- clock.tick(1000);
+ $row = $('body .toastify');
+ expect($row.length).toEqual(0);
- expect(fadeOutStub.notCalled).toEqual(true);
+ expect(hideCallback.calledOnce).toEqual(true);
+ });
+ it('hides a notification without timeout', function() {
+ var hideCallback = sinon.spy();
- $row2.find('.close').click();
- clock.tick(1000);
- expect(fadeOutStub.calledOnce).toEqual(true);
+ var notification = OC.Notification.show('');
- expect($el.is(':empty')).toEqual(false);
- fadeOutStub.yield();
- expect($el.is(':empty')).toEqual(true);
+ var $row = $('body .toastify');
+ expect($row.length).toEqual(1);
- fadeOutStub.restore();
+ OC.Notification.hide(notification, hideCallback);
+
+ // Give time to the hide animation to finish
+ clock.tick(1000);
+
+ $row = $('body .toastify');
+ expect($row.length).toEqual(0);
+
+ expect(hideCallback.calledOnce).toEqual(true);
+ });
});
- it('hides the first notification when calling hide without arguments', function() {
- var $row1 = OC.Notification.show('One');
- var $row2 = OC.Notification.show('Two');
+ it('cumulates several notifications', function() {
+ var $row1 = OC.Notification.showTemporary('One');
+ var $row2 = OC.Notification.showTemporary('Two', {timeout: 2000});
+ var $row3 = OC.Notification.showTemporary('Three');
- var $el = $('#notification');
- var $rows = $el.find('.row');
- expect($rows.length).toEqual(2);
+ var $el = $('body');
+ var $rows = $el.find('.toastify');
+ expect($rows.length).toEqual(3);
- OC.Notification.hide();
+ expect($rows.eq(0).is($row3)).toEqual(true);
+ expect($rows.eq(1).is($row2)).toEqual(true);
+ expect($rows.eq(2).is($row1)).toEqual(true);
- $rows = $el.find('.row');
- expect($rows.length).toEqual(1);
- expect($rows.eq(0).is($row2)).toEqual(true);
+ clock.tick(3000);
+
+ $rows = $el.find('.toastify');
+ expect($rows.length).toEqual(2);
+
+ expect($rows.eq(0).is($row3)).toEqual(true);
+ expect($rows.eq(1).is($row1)).toEqual(true);
});
it('hides the given notification when calling hide with argument', function() {
var $row1 = OC.Notification.show('One');
var $row2 = OC.Notification.show('Two');
- var $el = $('#notification');
- var $rows = $el.find('.row');
+ var $el = $('body');
+ var $rows = $el.find('.toastify');
expect($rows.length).toEqual(2);
OC.Notification.hide($row2);
+ clock.tick(3000);
- $rows = $el.find('.row');
+ $rows = $el.find('.toastify');
expect($rows.length).toEqual(1);
expect($rows.eq(0).is($row1)).toEqual(true);
});
});
describe('global ajax errors', function() {
var reloadStub, ajaxErrorStub, clock;
+ var notificationStub;
+ var waitTimeMs = 6500;
+ var oldCurrentUser;
beforeEach(function() {
+ oldCurrentUser = OC.currentUser;
+ OC.currentUser = 'dummy';
clock = sinon.useFakeTimers();
reloadStub = sinon.stub(OC, 'reload');
+ document.head.dataset.user = 'dummy'
+ notificationStub = sinon.stub(OC.Notification, 'show');
// unstub the error processing method
ajaxErrorStub = OC._processAjaxError;
ajaxErrorStub.restore();
window.initCore();
});
afterEach(function() {
+ OC.currentUser = oldCurrentUser;
reloadStub.restore();
+ notificationStub.restore();
clock.restore();
});
- it('reloads current page in case of auth error', function() {
- var dataProvider = [
- [200, false],
- [400, false],
- [0, true],
- [401, true],
- [302, true],
- [303, true],
- [307, true]
- ];
+ it('does not reload the page if the user was navigating away', function() {
+ var xhr = { status: 0 };
+ OC._userIsNavigatingAway = true;
+ clock.tick(100);
- for (var i = 0; i < dataProvider.length; i++) {
- var xhr = { status: dataProvider[i][0] };
- var expectedCall = dataProvider[i][1];
+ $(document).trigger(new $.Event('ajaxError'), xhr);
- reloadStub.reset();
- OC._reloadCalled = false;
+ clock.tick(waitTimeMs);
+ expect(reloadStub.notCalled).toEqual(true);
+ });
- $(document).trigger(new $.Event('ajaxError'), xhr);
+ it('shows a temporary notification if the connection is lost', function() {
+ var xhr = { status: 0 };
+ spyOn(OC, '_ajaxConnectionLostHandler');
- // trigger timers
- clock.tick(1000);
+ $(document).trigger(new $.Event('ajaxError'), xhr);
+ clock.tick(101);
- if (expectedCall) {
- expect(reloadStub.calledOnce).toEqual(true);
- } else {
- expect(reloadStub.notCalled).toEqual(true);
- }
- }
+ expect(OC._ajaxConnectionLostHandler.calls.count()).toBe(1);
+ });
+ });
+ describe('Snapper', function() {
+ var snapConstructorStub;
+ var snapperStub;
+ var clock;
+
+ beforeEach(function() {
+ snapConstructorStub = sinon.stub(window, 'Snap');
+ snapperStub = {};
+
+ snapperStub.enable = sinon.stub();
+ snapperStub.disable = sinon.stub();
+ snapperStub.close = sinon.stub();
+ snapperStub.on = sinon.stub();
+ snapperStub.state = sinon.stub().returns({
+ state: sinon.stub()
+ });
+
+ snapConstructorStub.returns(snapperStub);
+
+ clock = sinon.useFakeTimers();
+
+ // _.now could have been set to Date.now before Sinon replaced it
+ // with a fake version, so _.now must be stubbed to ensure that the
+ // fake Date.now will be called instead of the original one.
+ _.now = sinon.stub(_, 'now').callsFake(function() {
+ return new Date().getTime();
+ });
+
+ $('#testArea').append('<div id="app-navigation">The navigation bar</div><div id="app-content">Content</div>');
+ });
+ afterEach(function() {
+ snapConstructorStub.restore();
+
+ clock.restore();
+
+ _.now.restore();
+
+ // Remove the event handler for the resize event added to the window
+ // due to calling window.initCore() when there is an #app-navigation
+ // element.
+ $(window).off('resize');
+
+ viewport.reset();
});
- it('reload only called once in case of auth error', function() {
- var xhr = { status: 401 };
- $(document).trigger(new $.Event('ajaxError'), xhr);
- $(document).trigger(new $.Event('ajaxError'), xhr);
+ it('is enabled on a narrow screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapConstructorStub.calledOnce).toBe(true);
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ });
+ it('is disabled when disallowing the gesture on a narrow screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.disable.alwaysCalledWithExactly(true)).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+ });
+ it('is not disabled again when disallowing the gesture twice on a narrow screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.disable.alwaysCalledWithExactly(true)).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+ });
+ it('is enabled when allowing the gesture after disallowing it on a narrow screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.disable.alwaysCalledWithExactly(true)).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.allowNavigationBarSlideGesture();
- // trigger timers
+ expect(snapperStub.enable.calledTwice).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+ });
+ it('is not enabled again when allowing the gesture twice after disallowing it on a narrow screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.disable.alwaysCalledWithExactly(true)).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledTwice).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledTwice).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+ });
+ it('is disabled on a wide screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapConstructorStub.calledOnce).toBe(true);
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ });
+ it('is not disabled again when disallowing the gesture on a wide screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+ });
+ it('is not enabled when allowing the gesture after disallowing it on a wide screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+ });
+ it('is enabled when resizing to a narrow screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
clock.tick(1000);
- expect(reloadStub.calledOnce).toEqual(true);
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
});
- it('does not reload the page if the user was navigating away', function() {
- var xhr = { status: 0 };
- OC._userIsNavigatingAway = true;
- clock.tick(100);
+ it('is not enabled when resizing to a narrow screen after disallowing the gesture', function() {
+ viewport.set(1280);
- $(document).trigger(new $.Event('ajaxError'), xhr);
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
clock.tick(1000);
- expect(reloadStub.notCalled).toEqual(true);
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ });
+ it('is enabled when resizing to a narrow screen after disallowing the gesture and allowing it', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ });
+ it('is enabled when allowing the gesture after disallowing it and resizing to a narrow screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ });
+ it('is disabled when disallowing the gesture after disallowing it, resizing to a narrow screen and allowing it', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledTwice).toBe(true);
+ expect(snapperStub.disable.getCall(1).calledWithExactly(true)).toBe(true);
+ });
+ it('is disabled when resizing to a wide screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ viewport.set(1280);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+ });
+ it('is not disabled again when disallowing the gesture after resizing to a wide screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ viewport.set(1280);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+ });
+ it('is not enabled when allowing the gesture after disallowing it, resizing to a narrow screen and resizing to a wide screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ viewport.set(1280);
+
+ $(window).resize();
+
+ clock.tick(1000);
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledTwice).toBe(true);
+ expect(snapperStub.close.calledTwice).toBe(true);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledTwice).toBe(true);
+ expect(snapperStub.close.calledTwice).toBe(true);
});
});
});
-
diff --git a/core/js/tests/specs/files/clientSpec.js b/core/js/tests/specs/files/clientSpec.js
index 7673ec6e0fc..105af079ced 100644
--- a/core/js/tests/specs/files/clientSpec.js
+++ b/core/js/tests/specs/files/clientSpec.js
@@ -1,23 +1,8 @@
/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2015 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/>.
-*
-*/
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2015 ownCloud Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
/* global dav */
@@ -50,7 +35,7 @@ describe('OC.Files.Client tests', function() {
* status code
*
* @param {Promise} promise promise
- * @param {int} status status to test
+ * @param {number} status status to test
*/
function respondAndCheckStatus(promise, status) {
var successHandler = sinon.stub();
@@ -79,7 +64,7 @@ describe('OC.Files.Client tests', function() {
* status code
*
* @param {Promise} promise promise object
- * @param {int} status error status to test
+ * @param {number} status error status to test
*/
function respondAndCheckError(promise, status) {
var successHandler = sinon.stub();
@@ -87,14 +72,28 @@ describe('OC.Files.Client tests', function() {
promise.done(successHandler);
promise.fail(failHandler);
+ var errorXml =
+ '<d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">' +
+ ' <s:exception>Sabre\\DAV\\Exception\\SomeException</s:exception>' +
+ ' <s:message>Some error message</s:message>' +
+ '</d:error>';
+
+ var parser = new DOMParser();
+
requestDeferred.resolve({
status: status,
- body: ''
+ body: errorXml,
+ xhr: {
+ responseXML: parser.parseFromString(errorXml, 'application/xml')
+ }
});
promise.then(function() {
expect(failHandler.calledOnce).toEqual(true);
- expect(failHandler.calledWith(status)).toEqual(true);
+ expect(failHandler.getCall(0).args[0]).toEqual(status);
+ expect(failHandler.getCall(0).args[1].status).toEqual(status);
+ expect(failHandler.getCall(0).args[1].message).toEqual('Some error message');
+ expect(failHandler.getCall(0).args[1].exception).toEqual('Sabre\\DAV\\Exception\\SomeException');
expect(successHandler.notCalled).toEqual(true);
});
@@ -164,7 +163,7 @@ describe('OC.Files.Client tests', function() {
'd:resourcetype': '<d:collection/>',
'oc:id': '00000011oc2d13a6a068',
'oc:fileid': '11',
- 'oc:permissions': 'RDNVCK',
+ 'oc:permissions': 'GRDNVCK',
'oc:size': '120'
},
[
@@ -196,7 +195,7 @@ describe('OC.Files.Client tests', function() {
'd:resourcetype': '<d:collection/>',
'oc:id': '00000015oc2d13a6a068',
'oc:fileid': '15',
- 'oc:permissions': 'RDNVCK',
+ 'oc:permissions': 'GRDNVCK',
'oc:size': '100'
},
[
@@ -213,7 +212,7 @@ describe('OC.Files.Client tests', function() {
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('PROPFIND');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl + 'path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9');
- expect(requestStub.lastCall.args[2].Depth).toEqual(1);
+ expect(requestStub.lastCall.args[2].Depth).toEqual('1');
var props = getRequestedProperties(requestStub.lastCall.args[3]);
expect(props).toContain('{DAV:}getlastmodified');
@@ -224,6 +223,7 @@ describe('OC.Files.Client tests', function() {
expect(props).toContain('{http://owncloud.org/ns}fileid');
expect(props).toContain('{http://owncloud.org/ns}size');
expect(props).toContain('{http://owncloud.org/ns}permissions');
+ expect(props).toContain('{http://nextcloud.org/ns}is-encrypted');
});
it('sends PROPFIND to base url when empty path given', function() {
client.getFolderContents('');
@@ -257,11 +257,12 @@ describe('OC.Files.Client tests', function() {
expect(info.id).toEqual(51);
expect(info.path).toEqual('/path/to space/文件夹');
expect(info.name).toEqual('One.txt');
- expect(info.permissions).toEqual(27);
+ expect(info.permissions).toEqual(26);
expect(info.size).toEqual(250);
expect(info.mtime).toEqual(1436535485000);
expect(info.mimetype).toEqual('text/plain');
expect(info.etag).toEqual('559fcabd79a38');
+ expect(info.isEncrypted).toEqual(false);
// sub entry
info = response[1];
@@ -274,6 +275,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436536800000);
expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('66cfcabd79abb');
+ expect(info.isEncrypted).toEqual(false);
});
});
it('returns parent node in result if specified', function() {
@@ -303,6 +305,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436522405000);
expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('56cfcabd79abb');
+ expect(info.isEncrypted).toEqual(false);
// the two other entries follow
expect(response[1].id).toEqual(51);
@@ -422,6 +425,7 @@ describe('OC.Files.Client tests', function() {
expect(props).toContain('{http://owncloud.org/ns}fileid');
expect(props).toContain('{http://owncloud.org/ns}size');
expect(props).toContain('{http://owncloud.org/ns}permissions');
+ expect(props).toContain('{http://nextcloud.org/ns}is-encrypted');
});
it('parses the result list into a FileInfo array', function() {
var promise = client.getFilteredFiles({
@@ -448,7 +452,7 @@ describe('OC.Files.Client tests', function() {
expect(info.id).toEqual(11);
// file entry
- var info = response[1];
+ info = response[1];
expect(info instanceof OC.Files.FileInfo).toEqual(true);
expect(info.id).toEqual(51);
@@ -461,9 +465,7 @@ describe('OC.Files.Client tests', function() {
it('throws exception if arguments are missing', function() {
var thrown = null;
try {
- client.getFilteredFiles({
- systemTagIds: []
- });
+ client.getFilteredFiles({});
} catch (e) {
thrown = true;
}
@@ -475,7 +477,7 @@ describe('OC.Files.Client tests', function() {
describe('file info', function() {
var responseXml = dav.Client.prototype.parseMultiStatus(
'<?xml version="1.0" encoding="utf-8"?>' +
- '<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns">' +
+ '<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">' +
makeResponseBlock(
'/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/',
{
@@ -484,8 +486,9 @@ describe('OC.Files.Client tests', function() {
'd:resourcetype': '<d:collection/>',
'oc:id': '00000011oc2d13a6a068',
'oc:fileid': '11',
- 'oc:permissions': 'RDNVCK',
- 'oc:size': '120'
+ 'oc:permissions': 'GRDNVCK',
+ 'oc:size': '120',
+ 'nc:is-encrypted': '1'
},
[
'd:getcontenttype',
@@ -501,7 +504,7 @@ describe('OC.Files.Client tests', function() {
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('PROPFIND');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl + 'path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9');
- expect(requestStub.lastCall.args[2].Depth).toEqual(0);
+ expect(requestStub.lastCall.args[2].Depth).toEqual('0');
var props = getRequestedProperties(requestStub.lastCall.args[3]);
expect(props).toContain('{DAV:}getlastmodified');
@@ -512,6 +515,7 @@ describe('OC.Files.Client tests', function() {
expect(props).toContain('{http://owncloud.org/ns}fileid');
expect(props).toContain('{http://owncloud.org/ns}size');
expect(props).toContain('{http://owncloud.org/ns}permissions');
+ expect(props).toContain('{http://nextcloud.org/ns}is-encrypted');
});
it('parses the result into a FileInfo', function() {
var promise = client.getFileInfo('path/to space/文件夹');
@@ -537,6 +541,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436522405000);
expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('56cfcabd79abb');
+ expect(info.isEncrypted).toEqual(true);
});
});
it('properly parses entry inside root', function() {
@@ -551,7 +556,7 @@ describe('OC.Files.Client tests', function() {
'd:resourcetype': '<d:collection/>',
'oc:id': '00000011oc2d13a6a068',
'oc:fileid': '11',
- 'oc:permissions': 'RDNVCK',
+ 'oc:permissions': 'GRDNVCK',
'oc:size': '120'
},
[
@@ -585,6 +590,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436522405000);
expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('56cfcabd79abb');
+ expect(info.isEncrypted).toEqual(false);
});
});
it('rejects promise when an error occurred', function() {
@@ -642,14 +648,14 @@ describe('OC.Files.Client tests', function() {
function testPermission(permission, isFile, expectedPermissions) {
var promise = getFileInfoWithPermission(permission, isFile);
- promise.then(function(result) {
+ promise.then(function(status, result) {
expect(result.permissions).toEqual(expectedPermissions);
});
}
function testMountType(permission, isFile, expectedMountType) {
var promise = getFileInfoWithPermission(permission, isFile);
- promise.then(function(result) {
+ promise.then(function(status, result) {
expect(result.mountType).toEqual(expectedMountType);
});
}
@@ -657,43 +663,29 @@ describe('OC.Files.Client tests', function() {
it('properly parses file permissions', function() {
// permission, isFile, expectedPermissions
var testCases = [
- ['', true, OC.PERMISSION_READ],
- ['C', true, OC.PERMISSION_READ | OC.PERMISSION_CREATE],
- ['K', true, OC.PERMISSION_READ | OC.PERMISSION_CREATE],
- ['W', true, OC.PERMISSION_READ | OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE],
- ['D', true, OC.PERMISSION_READ | OC.PERMISSION_DELETE],
- ['R', true, OC.PERMISSION_READ | OC.PERMISSION_SHARE],
- ['CKWDR', true, OC.PERMISSION_ALL]
- ];
- _.each(testCases, function(testCase) {
- return testPermission.apply(testCase);
- });
- });
- it('properly parses folder permissions', function() {
- var testCases = [
- ['', false, OC.PERMISSION_READ],
- ['C', false, OC.PERMISSION_READ | OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE],
- ['K', false, OC.PERMISSION_READ | OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE],
- ['W', false, OC.PERMISSION_READ | OC.PERMISSION_UPDATE],
- ['D', false, OC.PERMISSION_READ | OC.PERMISSION_DELETE],
- ['R', false, OC.PERMISSION_READ | OC.PERMISSION_SHARE],
- ['CKWDR', false, OC.PERMISSION_ALL]
+ ['', true, OC.PERMISSION_NONE],
+ ['C', true, OC.PERMISSION_CREATE],
+ ['K', true, OC.PERMISSION_CREATE],
+ ['G', true, OC.PERMISSION_READ],
+ ['W', true, OC.PERMISSION_UPDATE],
+ ['D', true, OC.PERMISSION_DELETE],
+ ['R', true, OC.PERMISSION_SHARE],
+ ['CKGWDR', true, OC.PERMISSION_ALL]
];
-
_.each(testCases, function(testCase) {
- return testPermission.apply(testCase);
+ return testPermission.apply(this, testCase);
});
});
it('properly parses mount types', function() {
var testCases = [
- ['CKWDR', false, null],
+ ['CKGWDR', false, null],
['M', false, 'external'],
['S', false, 'shared'],
['SM', false, 'shared']
];
_.each(testCases, function(testCase) {
- return testMountType.apply(testCase);
+ return testMountType.apply(this, testCase);
});
});
});
diff --git a/core/js/tests/specs/jquery.avatarSpec.js b/core/js/tests/specs/jquery.avatarSpec.js
index f5caae10020..c01cd9b9603 100644
--- a/core/js/tests/specs/jquery.avatarSpec.js
+++ b/core/js/tests/specs/jquery.avatarSpec.js
@@ -1,17 +1,13 @@
/**
- * Copyright (c) 2015 Roeland Jago Douma <roeland@famdouma.nl>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2015 ownCloud Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
describe('jquery.avatar tests', function() {
var $div;
- var devicePixelRatio
+ var devicePixelRatio;
beforeEach(function() {
$('#testArea').append($('<div id="avatardiv">'));
@@ -19,100 +15,105 @@ describe('jquery.avatar tests', function() {
devicePixelRatio = window.devicePixelRatio;
window.devicePixelRatio = 1;
+
+ spyOn(window, 'Image').and.returnValue({
+ onload: function() {
+ },
+ onerror: function() {
+ }
+ });
});
afterEach(function() {
$div.remove();
- window.devicePixelRatio = devicePixelRatio
+ window.devicePixelRatio = devicePixelRatio;
});
describe('size', function() {
it('undefined', function() {
$div.avatar('foo');
- expect($div.height()).toEqual(64);
- expect($div.width()).toEqual(64);
+ expect(Math.round($div.height())).toEqual(64);
+ expect(Math.round($div.width())).toEqual(64);
});
it('undefined but div has height', function() {
$div.height(9);
$div.avatar('foo');
- expect($div.height()).toEqual(9);
- expect($div.width()).toEqual(9);
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
+
+ expect(Math.round($div.height())).toEqual(9);
+ expect(Math.round($div.width())).toEqual(9);
});
it('undefined but data size is set', function() {
$div.data('size', 10);
$div.avatar('foo');
- expect($div.height()).toEqual(10);
- expect($div.width()).toEqual(10);
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
+
+ expect(Math.round($div.height())).toEqual(10);
+ expect(Math.round($div.width())).toEqual(10);
});
it('defined', function() {
$div.avatar('foo', 8);
- expect($div.height()).toEqual(8);
- expect($div.width()).toEqual(8);
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
+
+ expect(Math.round($div.height())).toEqual(8);
+ expect(Math.round($div.width())).toEqual(8);
});
});
it('undefined user', function() {
spyOn($div, 'imageplaceholder');
+ spyOn($div, 'css');
$div.avatar();
- expect($div.imageplaceholder).toHaveBeenCalledWith('x');
+ expect($div.imageplaceholder).toHaveBeenCalledWith('?');
+ expect($div.css).toHaveBeenCalledWith('background-color', '#b9b9b9');
});
describe('no avatar', function() {
it('show placeholder for existing user', function() {
spyOn($div, 'imageplaceholder');
- $div.avatar('foo');
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- data: {displayname: 'bar'}
- })
- );
+ $div.avatar('foo', undefined, undefined, undefined, undefined, 'bar');
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
expect($div.imageplaceholder).toHaveBeenCalledWith('foo', 'bar');
});
it('show placeholder for non existing user', function() {
spyOn($div, 'imageplaceholder');
+ spyOn($div, 'css');
$div.avatar('foo');
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- data: {}
- })
- );
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
- expect($div.imageplaceholder).toHaveBeenCalledWith('foo', 'X');
+ expect($div.imageplaceholder).toHaveBeenCalledWith('?');
+ expect($div.css).toHaveBeenCalledWith('background-color', '#b9b9b9');
});
- it('show no placeholder', function() {
+ it('show no placeholder is ignored', function() {
spyOn($div, 'imageplaceholder');
+ spyOn($div, 'css');
$div.avatar('foo', undefined, undefined, true);
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- data: {}
- })
- );
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
- expect($div.imageplaceholder.calls.any()).toEqual(false);
- expect($div.css('display')).toEqual('none');
+ expect($div.imageplaceholder).toHaveBeenCalledWith('?');
+ expect($div.css).toHaveBeenCalledWith('background-color', '#b9b9b9');
});
});
@@ -125,24 +126,24 @@ describe('jquery.avatar tests', function() {
window.devicePixelRatio = 1;
$div.avatar('foo', 32);
- expect(fakeServer.requests[0].method).toEqual('GET');
- expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/avatar/foo/32');
+ expect(window.Image).toHaveBeenCalled();
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/32');
});
it('high DPI icon', function() {
window.devicePixelRatio = 4;
$div.avatar('foo', 32);
- expect(fakeServer.requests[0].method).toEqual('GET');
- expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/avatar/foo/128');
+ expect(window.Image).toHaveBeenCalled();
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/128');
});
it('high DPI icon round up size', function() {
window.devicePixelRatio = 1.9;
$div.avatar('foo', 32);
- expect(fakeServer.requests[0].method).toEqual('GET');
- expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/avatar/foo/61');
+ expect(window.Image).toHaveBeenCalled();
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/61');
});
});
@@ -154,17 +155,12 @@ describe('jquery.avatar tests', function() {
it('default (no ie8 fix)', function() {
$div.avatar('foo', 32);
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'image/jpeg' },
- ''
- );
-
- var img = $div.children('img')[0];
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onload();
- expect(img.height).toEqual(32);
- expect(img.width).toEqual(32);
- expect(img.src).toEqual('http://localhost/index.php/avatar/foo/32');
+ expect(window.Image().height).toEqual(32);
+ expect(window.Image().width).toEqual(32);
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/32');
});
it('default high DPI icon', function() {
@@ -172,37 +168,23 @@ describe('jquery.avatar tests', function() {
$div.avatar('foo', 32);
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'image/jpeg' },
- ''
- );
-
- var img = $div.children('img')[0];
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onload();
- expect(img.height).toEqual(32);
- expect(img.width).toEqual(32);
- expect(img.src).toEqual('http://localhost/index.php/avatar/foo/61');
+ expect(window.Image().height).toEqual(32);
+ expect(window.Image().width).toEqual(32);
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/61');
});
- it('with ie8 fix', function() {
- sinon.stub(Math, 'random', function() {
- return 0.5;
- });
-
+ it('with ie8 fix (ignored)', function() {
$div.avatar('foo', 32, true);
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'image/jpeg' },
- ''
- );
-
- var img = $div.children('img')[0];
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onload();
- expect(img.height).toEqual(32);
- expect(img.width).toEqual(32);
- expect(img.src).toEqual('http://localhost/index.php/avatar/foo/32#500');
+ expect(window.Image().height).toEqual(32);
+ expect(window.Image().width).toEqual(32);
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/32');
});
it('unhide div', function() {
@@ -210,13 +192,12 @@ describe('jquery.avatar tests', function() {
$div.avatar('foo', 32);
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'image/jpeg' },
- ''
- );
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onload();
- expect($div.css('display')).toEqual('block');
+ expect(window.Image().height).toEqual(32);
+ expect(window.Image().width).toEqual(32);
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/32');
});
it('callback called', function() {
@@ -228,12 +209,12 @@ describe('jquery.avatar tests', function() {
observer.callback();
});
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'image/jpeg' },
- ''
- );
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onload();
+ expect(window.Image().height).toEqual(32);
+ expect(window.Image().width).toEqual(32);
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/32');
expect(observer.callback).toHaveBeenCalled();
});
});
diff --git a/core/js/tests/specs/jquery.contactsmenuSpec.js b/core/js/tests/specs/jquery.contactsmenuSpec.js
new file mode 100644
index 00000000000..62aaef89edc
--- /dev/null
+++ b/core/js/tests/specs/jquery.contactsmenuSpec.js
@@ -0,0 +1,235 @@
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+describe('jquery.contactsMenu tests', function() {
+
+ var $selector1, $selector2, $appendTo;
+
+ beforeEach(function() {
+ $('#testArea').append($('<div id="selector1">'));
+ $('#testArea').append($('<div id="selector2">'));
+ $('#testArea').append($('<div id="appendTo">'));
+ $selector1 = $('#selector1');
+ $selector2 = $('#selector2');
+ $appendTo = $('#appendTo');
+ });
+
+ afterEach(function() {
+ $selector1.off();
+ $selector1.remove();
+ $selector2.off();
+ $selector2.remove();
+ $appendTo.remove();
+ });
+
+ describe('shareType', function() {
+ it('stops if type not supported', function() {
+ $selector1.contactsMenu('user', 1, $appendTo);
+ expect($appendTo.children().length).toEqual(0);
+
+ $selector1.contactsMenu('user', 2, $appendTo);
+ expect($appendTo.children().length).toEqual(0);
+
+ $selector1.contactsMenu('user', 3, $appendTo);
+ expect($appendTo.children().length).toEqual(0);
+
+ $selector1.contactsMenu('user', 5, $appendTo);
+ expect($appendTo.children().length).toEqual(0);
+ });
+
+ it('append list if shareType supported', function() {
+ $selector1.contactsMenu('user', 0, $appendTo);
+ expect($appendTo.children().length).toEqual(1);
+ expect($appendTo.html().replace(/[\r\n\t]?(\ \ +)?/g, '')).toEqual('<div class="menu popovermenu menu-left hidden contactsmenu-popover"><ul><li><a><span class="icon-loading-small"></span></a></li></ul></div>');
+ });
+ });
+
+ describe('open on click', function() {
+ it('with one selector', function() {
+ $selector1.contactsMenu('user', 0, $appendTo);
+ expect($appendTo.children().length).toEqual(1);
+ expect($appendTo.find('div.contactsmenu-popover').hasClass('hidden')).toEqual(true);
+ $selector1.click();
+ expect($appendTo.find('div.contactsmenu-popover').hasClass('hidden')).toEqual(false);
+ });
+
+ it('with multiple selectors - 1', function() {
+ $('#selector1, #selector2').contactsMenu('user', 0, $appendTo);
+
+ expect($appendTo.children().length).toEqual(1);
+ expect($appendTo.find('div.contactsmenu-popover').hasClass('hidden')).toEqual(true);
+ $selector1.click();
+ expect($appendTo.find('div.contactsmenu-popover').hasClass('hidden')).toEqual(false);
+ });
+
+ it('with multiple selectors - 2', function() {
+ $('#selector1, #selector2').contactsMenu('user', 0, $appendTo);
+
+ expect($appendTo.children().length).toEqual(1);
+ expect($appendTo.find('div.contactsmenu-popover').hasClass('hidden')).toEqual(true);
+ $selector2.click();
+ expect($appendTo.find('div.contactsmenu-popover').hasClass('hidden')).toEqual(false);
+ });
+
+ it ('should close when clicking the selector again - 1', function() {
+ $('#selector1, #selector2').contactsMenu('user', 0, $appendTo);
+
+ expect($appendTo.children().length).toEqual(1);
+ expect($appendTo.find('div').hasClass('hidden')).toEqual(true);
+ $selector1.click();
+ expect($appendTo.find('div').hasClass('hidden')).toEqual(false);
+ $selector1.click();
+ expect($appendTo.find('div').hasClass('hidden')).toEqual(true);
+ });
+
+ it ('should close when clicking the selector again - 1', function() {
+ $('#selector1, #selector2').contactsMenu('user', 0, $appendTo);
+
+ expect($appendTo.children().length).toEqual(1);
+ expect($appendTo.find('div').hasClass('hidden')).toEqual(true);
+ $selector1.click();
+ expect($appendTo.find('div').hasClass('hidden')).toEqual(false);
+ $selector2.click();
+ expect($appendTo.find('div').hasClass('hidden')).toEqual(true);
+ });
+ });
+
+ describe('send requests to the server and render', function() {
+ it('load a topaction only', function(done) {
+ $('#selector1, #selector2').contactsMenu('user', 0, $appendTo);
+ $selector1.click();
+
+ expect(fakeServer.requests[0].method).toEqual('POST');
+ expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/contactsmenu/findOne');
+ fakeServer.requests[0].respond(
+ 200,
+ { 'Content-Type': 'application/json; charset=utf-8' },
+ JSON.stringify({
+ "id": null,
+ "fullName": "Name 123",
+ "topAction": {
+ "title": "bar@baz.wtf",
+ "icon": "foo.svg",
+ "hyperlink": "mailto:bar%40baz.wtf"},
+ "actions": []
+ })
+ );
+
+ $selector1.on('load', function() {
+ // FIXME: don't compare HTML one to one but check specific text in the output
+ expect($appendTo.html().replace(/[\r\n\t]?(\ \ +)?/g, '')).toEqual('<div class="menu popovermenu menu-left contactsmenu-popover loaded" style="display: block;"><ul><li class="hidden"><a><span class="icon-loading-small"></span></a></li><li><a href="mailto:bar%40baz.wtf"><img src="foo.svg"><span>bar@baz.wtf</span></a></li></ul></div>');
+
+ done();
+ });
+ });
+
+ it('load topaction and more actions', function(done) {
+ $('#selector1, #selector2').contactsMenu('user', 0, $appendTo);
+ $selector1.click();
+
+ fakeServer.requests[0].respond(
+ 200,
+ { 'Content-Type': 'application/json; charset=utf-8' },
+ JSON.stringify({
+ "id": null,
+ "fullName": "Name 123",
+ "topAction": {
+ "title": "bar@baz.wtf",
+ "icon": "foo.svg",
+ "hyperlink": "mailto:bar%40baz.wtf"},
+ "actions": [{
+ "title": "Details",
+ "icon": "details.svg",
+ "hyperlink": "http:\/\/localhost\/index.php\/apps\/contacts"
+ }]
+ })
+ );
+ expect(fakeServer.requests[0].method).toEqual('POST');
+ expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/contactsmenu/findOne');
+
+ $selector1.on('load', function() {
+ // FIXME: don't compare HTML one to one but check specific text in the output
+ expect($appendTo.html().replace(/[\r\n\t]?(\ \ +)?/g, '')).toEqual('<div class="menu popovermenu menu-left contactsmenu-popover loaded" style="display: block;"><ul><li class="hidden"><a><span class="icon-loading-small"></span></a></li><li><a href="mailto:bar%40baz.wtf"><img src="foo.svg"><span>bar@baz.wtf</span></a></li><li><a href="http://localhost/index.php/apps/contacts"><img src="details.svg"><span>Details</span></a></li></ul></div>');
+
+ done();
+ });
+ });
+
+ it('load no actions', function(done) {
+ $('#selector1, #selector2').contactsMenu('user', 0, $appendTo);
+ $selector1.click();
+
+ fakeServer.requests[0].respond(
+ 200,
+ { 'Content-Type': 'application/json; charset=utf-8' },
+ JSON.stringify({
+ "id": null,
+ "fullName": "Name 123",
+ "topAction": null,
+ "actions": []
+ })
+ );
+ expect(fakeServer.requests[0].method).toEqual('POST');
+ expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/contactsmenu/findOne');
+
+ $selector1.on('load', function() {
+ // FIXME: don't compare HTML one to one but check specific text in the output
+ expect($appendTo.html().replace(/[\r\n\t]?(\ \ +)?/g, '')).toEqual('<div class="menu popovermenu menu-left contactsmenu-popover loaded" style="display: block;"><ul><li class="hidden"><a><span class="icon-loading-small"></span></a></li><li><a href="#"><span>No action available</span></a></li></ul></div>');
+
+ done();
+ });
+ });
+
+ it('should throw an error', function(done) {
+ $('#selector1, #selector2').contactsMenu('user', 0, $appendTo);
+ $selector1.click();
+
+ fakeServer.requests[0].respond(
+ 400,
+ { 'Content-Type': 'application/json; charset=utf-8' },
+ JSON.stringify([])
+ );
+ expect(fakeServer.requests[0].method).toEqual('POST');
+ expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/contactsmenu/findOne');
+
+ $selector1.on('loaderror', function() {
+ // FIXME: don't compare HTML one to one but check specific text in the output
+ expect($appendTo.html().replace(/[\r\n\t]?(\ \ +)?/g, '')).toEqual('<div class="menu popovermenu menu-left contactsmenu-popover loaded" style="display: block;"><ul><li class="hidden"><a><span class="icon-loading-small"></span></a></li><li><a href="#"><span>Error fetching contact actions</span></a></li></ul></div>');
+
+ done();
+ });
+ });
+
+ it('should handle 404', function(done) {
+ $('#selector1, #selector2').contactsMenu('user', 0, $appendTo);
+ $selector1.click();
+
+ fakeServer.requests[0].respond(
+ 404,
+ { 'Content-Type': 'application/json; charset=utf-8' },
+ JSON.stringify([])
+ );
+ expect(fakeServer.requests[0].method).toEqual('POST');
+ expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/contactsmenu/findOne');
+
+ $selector1.on('loaderror', function() {
+ // FIXME: don't compare HTML one to one but check specific text in the output
+ expect($appendTo.html().replace(/[\r\n\t]?(\ \ +)?/g, '')).toEqual('<div class="menu popovermenu menu-left contactsmenu-popover loaded" style="display: block;"><ul><li class="hidden"><a><span class="icon-loading-small"></span></a></li><li><a href="#"><span>No action available</span></a></li></ul></div>');
+
+ done();
+ });
+ });
+
+ it('click anywhere else to close the menu', function() {
+ $('#selector1, #selector2').contactsMenu('user', 0, $appendTo);
+
+ expect($appendTo.find('div').hasClass('hidden')).toEqual(true);
+ $selector1.click();
+ expect($appendTo.find('div').hasClass('hidden')).toEqual(false);
+ $(document).click();
+ expect($appendTo.find('div').hasClass('hidden')).toEqual(true);
+ });
+ });
+});
diff --git a/core/js/tests/specs/jquery.placeholderSpec.js b/core/js/tests/specs/jquery.placeholderSpec.js
new file mode 100644
index 00000000000..436defdd703
--- /dev/null
+++ b/core/js/tests/specs/jquery.placeholderSpec.js
@@ -0,0 +1,38 @@
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+describe('jquery.placeholder tests', function() {
+
+ var $div;
+
+ beforeEach(function() {
+ $('#testArea').append($('<div id="placeholderdiv">'));
+ $div = $('#placeholderdiv');
+ });
+
+ afterEach(function() {
+ $div.remove();
+ });
+
+ describe('placeholder text', function() {
+ it('shows one first letter if one word in a input text', function() {
+ spyOn($div, 'html');
+ $div.imageplaceholder('Seed', 'Name')
+ expect($div.html).toHaveBeenCalledWith('N');
+ });
+
+ it('shows two first letters if two words in a input text', function() {
+ spyOn($div, 'html');
+ $div.imageplaceholder('Seed', 'First Second')
+ expect($div.html).toHaveBeenCalledWith('FS');
+ });
+
+ it('shows two first letters if more then two words in a input text', function() {
+ spyOn($div, 'html');
+ $div.imageplaceholder('Seed', 'First Second Middle')
+ expect($div.html).toHaveBeenCalledWith('FS');
+ });
+ });
+});
diff --git a/core/js/tests/specs/l10nSpec.js b/core/js/tests/specs/l10nSpec.js
index 2ceb2f4a916..bd93a13fe74 100644
--- a/core/js/tests/specs/l10nSpec.js
+++ b/core/js/tests/specs/l10nSpec.js
@@ -1,26 +1,28 @@
/**
- * 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.
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2014 ownCloud Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
describe('OC.L10N tests', function() {
var TEST_APP = 'jsunittestapp';
beforeEach(function() {
- OC.appswebroots[TEST_APP] = OC.webroot + '/apps3/jsunittestapp';
+ window._oc_appswebroots[TEST_APP] = OC.getRootPath() + '/apps3/jsunittestapp';
+
+ window.OC = window.OC ?? {}
+ window.OC.appswebroots = window.OC.appswebroots || {}
+ window.OC.appswebroots[TEST_APP] = OC.getRootPath() + '/apps3/jsunittestapp'
});
afterEach(function() {
- delete OC.L10N._bundles[TEST_APP];
- delete OC.appswebroots[TEST_APP];
+ OC.L10N._unregister(TEST_APP);
+ delete window._oc_appswebroots[TEST_APP];
+ delete window.OC.appswebroots[TEST_APP];
});
describe('text translation', function() {
beforeEach(function() {
+ spyOn(console, 'warn');
OC.L10N.register(TEST_APP, {
'Hello world!': 'Hallo Welt!',
'Hello {name}, the weather is {weather}': 'Hallo {name}, das Wetter ist {weather}',
@@ -28,7 +30,7 @@ describe('OC.L10N tests', function() {
});
});
it('returns untranslated text when no bundle exists', function() {
- delete OC.L10N._bundles[TEST_APP];
+ OC.L10N._unregister(TEST_APP);
expect(t(TEST_APP, 'unknown text')).toEqual('unknown text');
});
it('returns untranslated text when no key exists', function() {
@@ -52,6 +54,11 @@ describe('OC.L10N tests', function() {
t(TEST_APP, 'Hello {name}', {name: '<strong>Steve</strong>'}, null, {escape: false})
).toEqual('Hello <strong>Steve</strong>');
});
+ it('uses DOMPurify to escape the text', function() {
+ expect(
+ t(TEST_APP, '<strong>These are your search results<script>alert(1)</script></strong>', null, {escape: false})
+ ).toEqual('<strong>These are your search results</strong>');
+ });
it('keeps old texts when registering existing bundle', function() {
OC.L10N.register(TEST_APP, {
'sunny': 'sonnig',
@@ -78,6 +85,7 @@ describe('OC.L10N tests', function() {
}
it('generates plural for default text when translation does not exist', function() {
+ spyOn(console, 'warn');
OC.L10N.register(TEST_APP, {
});
expect(
@@ -94,78 +102,12 @@ describe('OC.L10N tests', function() {
).toEqual('download 1024 files');
});
it('generates plural with default function when no forms specified', function() {
+ spyOn(console, 'warn');
OC.L10N.register(TEST_APP, {
'_download %n file_::_download %n files_':
['%n Datei herunterladen', '%n Dateien herunterladen']
});
checkPlurals();
});
- it('generates plural with generated function when forms is specified', function() {
- OC.L10N.register(TEST_APP, {
- '_download %n file_::_download %n files_':
- ['%n Datei herunterladen', '%n Dateien herunterladen']
- }, 'nplurals=2; plural=(n != 1);');
- checkPlurals();
- });
- it('generates plural with function when forms is specified as function', function() {
- OC.L10N.register(TEST_APP, {
- '_download %n file_::_download %n files_':
- ['%n Datei herunterladen', '%n Dateien herunterladen']
- }, function(n) {
- return {
- nplurals: 2,
- plural: (n !== 1) ? 1 : 0
- };
- });
- checkPlurals();
- });
- });
- describe('async loading of translations', function() {
- it('loads bundle for given app and calls callback', function() {
- var localeStub = sinon.stub(OC, 'getLocale').returns('zh_CN');
- var callbackStub = sinon.stub();
- var promiseStub = sinon.stub();
- OC.L10N.load(TEST_APP, callbackStub).then(promiseStub);
- expect(callbackStub.notCalled).toEqual(true);
- expect(promiseStub.notCalled).toEqual(true);
- expect(fakeServer.requests.length).toEqual(1);
- var req = fakeServer.requests[0];
- expect(req.url).toEqual(
- OC.webroot + '/apps3/' + TEST_APP + '/l10n/zh_CN.json'
- );
- req.respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- translations: {'Hello world!': '你好世界!'},
- pluralForm: 'nplurals=2; plural=(n != 1);'
- })
- );
-
- expect(callbackStub.calledOnce).toEqual(true);
- expect(promiseStub.calledOnce).toEqual(true);
- expect(t(TEST_APP, 'Hello world!')).toEqual('你好世界!');
- localeStub.restore();
- });
- it('calls callback if translation already available', function() {
- var promiseStub = sinon.stub();
- var callbackStub = sinon.stub();
- OC.L10N.register(TEST_APP, {
- 'Hello world!': 'Hallo Welt!'
- });
- OC.L10N.load(TEST_APP, callbackStub).then(promiseStub);
- expect(callbackStub.calledOnce).toEqual(true);
- expect(promiseStub.calledOnce).toEqual(true);
- expect(fakeServer.requests.length).toEqual(0);
- });
- it('calls callback if locale is en', function() {
- var localeStub = sinon.stub(OC, 'getLocale').returns('en');
- var promiseStub = sinon.stub();
- var callbackStub = sinon.stub();
- OC.L10N.load(TEST_APP, callbackStub).then(promiseStub);
- expect(callbackStub.calledOnce).toEqual(true);
- expect(promiseStub.calledOnce).toEqual(true);
- expect(fakeServer.requests.length).toEqual(0);
- });
});
});
diff --git a/core/js/tests/specs/mimeTypeSpec.js b/core/js/tests/specs/mimeTypeSpec.js
index 182941de1a9..4fe5481541d 100644
--- a/core/js/tests/specs/mimeTypeSpec.js
+++ b/core/js/tests/specs/mimeTypeSpec.js
@@ -1,21 +1,7 @@
/**
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2015 ownCloud Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
describe('MimeType tests', function() {
@@ -26,17 +12,17 @@ describe('MimeType tests', function() {
beforeEach(function() {
_files = OC.MimeTypeList.files;
_aliases = OC.MimeTypeList.aliases;
- _theme = OC.MimeTypeList.themes['abc'];
+ _theme = OC.MimeTypeList.themes.abc;
OC.MimeTypeList.files = ['folder', 'folder-shared', 'folder-external', 'foo-bar', 'foo', 'file'];
OC.MimeTypeList.aliases = {'app/foobar': 'foo/bar'};
- OC.MimeTypeList.themes['abc'] = ['folder'];
+ OC.MimeTypeList.themes.abc = ['folder'];
});
afterEach(function() {
OC.MimeTypeList.files = _files;
OC.MimeTypeList.aliases = _aliases;
- OC.MimeTypeList.themes['abc'] = _theme;
+ OC.MimeTypeList.themes.abc = _theme;
});
describe('_getFile', function() {
@@ -100,7 +86,7 @@ describe('MimeType tests', function() {
it('return the url for the mimetype file', function() {
var res = OC.MimeType.getIconUrl('file');
- expect(res).toEqual(OC.webroot + '/core/img/filetypes/file.svg');
+ expect(res).toEqual(OC.getRootPath() + '/core/img/filetypes/file.svg');
});
it('test if the cache works correctly', function() {
@@ -109,16 +95,16 @@ describe('MimeType tests', function() {
var res = OC.MimeType.getIconUrl('dir');
expect(Object.keys(OC.MimeType._mimeTypeIcons).length).toEqual(1);
- expect(OC.MimeType._mimeTypeIcons['dir']).toEqual(res);
+ expect(OC.MimeType._mimeTypeIcons.dir).toEqual(res);
- var res = OC.MimeType.getIconUrl('dir-shared');
+ res = OC.MimeType.getIconUrl('dir-shared');
expect(Object.keys(OC.MimeType._mimeTypeIcons).length).toEqual(2);
expect(OC.MimeType._mimeTypeIcons['dir-shared']).toEqual(res);
});
it('test if alaiases are converted correctly', function() {
var res = OC.MimeType.getIconUrl('app/foobar');
- expect(res).toEqual(OC.webroot + '/core/img/filetypes/foo-bar.svg');
+ expect(res).toEqual(OC.getRootPath() + '/core/img/filetypes/foo-bar.svg');
expect(OC.MimeType._mimeTypeIcons['foo/bar']).toEqual(res);
});
});
@@ -139,12 +125,12 @@ describe('MimeType tests', function() {
it('test if theme path is used if a theme icon is availble', function() {
var res = OC.MimeType.getIconUrl('dir');
- expect(res).toEqual(OC.webroot + '/themes/abc/core/img/filetypes/folder.svg');
+ expect(res).toEqual(OC.getRootPath() + '/themes/abc/core/img/filetypes/folder.svg');
});
it('test if we fallback to the default theme if no icon is available in the theme', function() {
var res = OC.MimeType.getIconUrl('dir-shared');
- expect(res).toEqual(OC.webroot + '/core/img/filetypes/folder-shared.svg');
+ expect(res).toEqual(OC.getRootPath() + '/core/img/filetypes/folder-shared.svg');
});
});
});
diff --git a/core/js/tests/specs/oc-backbone-webdavSpec.js b/core/js/tests/specs/oc-backbone-webdavSpec.js
index 97281e982ce..bf4d6eef6ca 100644
--- a/core/js/tests/specs/oc-backbone-webdavSpec.js
+++ b/core/js/tests/specs/oc-backbone-webdavSpec.js
@@ -1,23 +1,8 @@
/**
-* 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/>.
-*
-*/
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2014 ownCloud Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
/* global dav */
@@ -71,7 +56,7 @@ describe('Backbone Webdav extension', function() {
});
});
- it('makes a POST request to create model into collection', function() {
+ it('makes a POST request to create model into collection', function(done) {
var collection = new TestCollection();
var model = collection.create({
firstName: 'Hello',
@@ -104,10 +89,14 @@ describe('Backbone Webdav extension', function() {
}
});
- expect(model.id).toEqual('123');
+ setTimeout(function() {
+ expect(model.id).toEqual('123');
+
+ done();
+ }, 0)
});
- it('uses PROPFIND to retrieve collection', function() {
+ it('uses PROPFIND to retrieve collection', function(done) {
var successStub = sinon.stub();
var errorStub = sinon.stub();
var collection = new TestCollection();
@@ -164,23 +153,27 @@ describe('Backbone Webdav extension', function() {
]
});
- expect(collection.length).toEqual(2);
+ setTimeout(function() {
+ expect(collection.length).toEqual(2);
- var model = collection.get('123');
- expect(model.id).toEqual('123');
- expect(model.get('firstName')).toEqual('Hello');
- expect(model.get('lastName')).toEqual('World');
+ var model = collection.get('123');
+ expect(model.id).toEqual('123');
+ expect(model.get('firstName')).toEqual('Hello');
+ expect(model.get('lastName')).toEqual('World');
+
+ model = collection.get('456');
+ expect(model.id).toEqual('456');
+ expect(model.get('firstName')).toEqual('Test');
+ expect(model.get('lastName')).toEqual('Person');
- model = collection.get('456');
- expect(model.id).toEqual('456');
- expect(model.get('firstName')).toEqual('Test');
- expect(model.get('lastName')).toEqual('Person');
+ expect(successStub.calledOnce).toEqual(true);
+ expect(errorStub.notCalled).toEqual(true);
- expect(successStub.calledOnce).toEqual(true);
- expect(errorStub.notCalled).toEqual(true);
+ done();
+ }, 0)
});
- function testMethodError(doCall) {
+ function testMethodError(doCall, done) {
var successStub = sinon.stub();
var errorStub = sinon.stub();
@@ -191,20 +184,24 @@ describe('Backbone Webdav extension', function() {
body: ''
});
- expect(successStub.notCalled).toEqual(true);
- expect(errorStub.calledOnce).toEqual(true);
+ setTimeout(function() {
+ expect(successStub.notCalled).toEqual(true);
+ expect(errorStub.calledOnce).toEqual(true);
+
+ done();
+ }, 0)
}
- it('calls error handler if error status in PROPFIND response', function() {
+ it('calls error handler if error status in PROPFIND response', function(done) {
testMethodError(function(success, error) {
var collection = new TestCollection();
collection.fetch({
success: success,
error: error
});
- });
+ }, done);
});
- it('calls error handler if error status in POST response', function() {
+ it('calls error handler if error status in POST response', function(done) {
testMethodError(function(success, error) {
var collection = new TestCollection();
collection.create({
@@ -214,7 +211,7 @@ describe('Backbone Webdav extension', function() {
success: success,
error: error
});
- });
+ }, done);
});
});
describe('models', function() {
@@ -281,7 +278,7 @@ describe('Backbone Webdav extension', function() {
expect(model.get('married')).toEqual(true);
});
- it('uses PROPFIND to fetch single model', function() {
+ it('uses PROPFIND to fetch single model', function(done) {
var model = new TestModel({
id: '123'
});
@@ -319,11 +316,15 @@ describe('Backbone Webdav extension', function() {
}
});
- expect(model.id).toEqual('123');
- expect(model.get('firstName')).toEqual('Hello');
- expect(model.get('lastName')).toEqual('World');
- expect(model.get('age')).toEqual(35);
- expect(model.get('married')).toEqual(true);
+ setTimeout(function() {
+ expect(model.id).toEqual('123');
+ expect(model.get('firstName')).toEqual('Hello');
+ expect(model.get('lastName')).toEqual('World');
+ expect(model.get('age')).toEqual(35);
+ expect(model.get('married')).toEqual(true);
+
+ done();
+ });
});
it('makes a DELETE request to destroy model', function() {
var model = new TestModel({
@@ -350,7 +351,7 @@ describe('Backbone Webdav extension', function() {
});
});
- function testMethodError(doCall) {
+ function testMethodError(doCall, done) {
var successStub = sinon.stub();
var errorStub = sinon.stub();
@@ -361,20 +362,24 @@ describe('Backbone Webdav extension', function() {
body: ''
});
- expect(successStub.notCalled).toEqual(true);
- expect(errorStub.calledOnce).toEqual(true);
+ setTimeout(function() {
+ expect(successStub.notCalled).toEqual(true);
+ expect(errorStub.calledOnce).toEqual(true);
+
+ done();
+ });
}
- it('calls error handler if error status in PROPFIND response', function() {
+ it('calls error handler if error status in PROPFIND response', function(done) {
testMethodError(function(success, error) {
var model = new TestModel();
model.fetch({
success: success,
error: error
});
- });
+ }, done);
});
- it('calls error handler if error status in PROPPATCH response', function() {
+ it('calls error handler if error status in PROPPATCH response', function(done) {
testMethodError(function(success, error) {
var model = new TestModel();
model.save({
@@ -383,7 +388,7 @@ describe('Backbone Webdav extension', function() {
success: success,
error: error
});
- });
+ }, done);
});
});
});
diff --git a/core/js/tests/specs/public/commentsSpec.js b/core/js/tests/specs/public/commentsSpec.js
new file mode 100644
index 00000000000..6e15ddca6a7
--- /dev/null
+++ b/core/js/tests/specs/public/commentsSpec.js
@@ -0,0 +1,38 @@
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+describe('OCP.Comments tests', function() {
+ function dataProvider() {
+ return [
+ {input: 'nextcloud.com', expected: 'nextcloud.com'},
+ {input: 'http://nextcloud.com', expected: '<a class="external" target="_blank" rel="noopener noreferrer" href="http://nextcloud.com">http://nextcloud.com</a>'},
+ {input: 'https://nextcloud.com', expected: '<a class="external" target="_blank" rel="noopener noreferrer" href="https://nextcloud.com">nextcloud.com</a>'},
+ {input: 'hi nextcloud.com', expected: 'hi nextcloud.com'},
+ {input: 'hi http://nextcloud.com', expected: 'hi <a class="external" target="_blank" rel="noopener noreferrer" href="http://nextcloud.com">http://nextcloud.com</a>'},
+ {input: 'hi https://nextcloud.com', expected: 'hi <a class="external" target="_blank" rel="noopener noreferrer" href="https://nextcloud.com">nextcloud.com</a>'},
+ {input: 'nextcloud.com foobar', expected: 'nextcloud.com foobar'},
+ {input: 'http://nextcloud.com foobar', expected: '<a class="external" target="_blank" rel="noopener noreferrer" href="http://nextcloud.com">http://nextcloud.com</a> foobar'},
+ {input: 'https://nextcloud.com foobar', expected: '<a class="external" target="_blank" rel="noopener noreferrer" href="https://nextcloud.com">nextcloud.com</a> foobar'},
+ {input: 'hi nextcloud.com foobar', expected: 'hi nextcloud.com foobar'},
+ {input: 'hi http://nextcloud.com foobar', expected: 'hi <a class="external" target="_blank" rel="noopener noreferrer" href="http://nextcloud.com">http://nextcloud.com</a> foobar'},
+ {input: 'hi https://nextcloud.com foobar', expected: 'hi <a class="external" target="_blank" rel="noopener noreferrer" href="https://nextcloud.com">nextcloud.com</a> foobar'},
+ {input: 'hi help.nextcloud.com/category/topic foobar', expected: 'hi help.nextcloud.com/category/topic foobar'},
+ {input: 'hi http://help.nextcloud.com/category/topic foobar', expected: 'hi <a class="external" target="_blank" rel="noopener noreferrer" href="http://help.nextcloud.com/category/topic">http://help.nextcloud.com/category/topic</a> foobar'},
+ {input: 'hi https://help.nextcloud.com/category/topic foobar', expected: 'hi <a class="external" target="_blank" rel="noopener noreferrer" href="https://help.nextcloud.com/category/topic">help.nextcloud.com/category/topic</a> foobar'},
+ {input: 'noreply@nextcloud.com', expected: 'noreply@nextcloud.com'},
+ {input: 'hi noreply@nextcloud.com', expected: 'hi noreply@nextcloud.com'},
+ {input: 'hi <noreply@nextcloud.com>', expected: 'hi <noreply@nextcloud.com>'},
+ {input: 'FirebaseInstanceId.getInstance().deleteInstanceId()', expected: 'FirebaseInstanceId.getInstance().deleteInstanceId()'},
+ {input: 'I mean...it', expected: 'I mean...it'},
+ ];
+ }
+
+ it('should parse URLs only', function () {
+ dataProvider().forEach(function(data) {
+ var result = OCP.Comments.plainToRich(data.input);
+ expect(result).toEqual(data.expected);
+ });
+ });
+});
diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js
index 6dd8657a077..9f75ad501d1 100644
--- a/core/js/tests/specs/setupchecksSpec.js
+++ b/core/js/tests/specs/setupchecksSpec.js
@@ -1,11 +1,7 @@
/**
- * Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2015 ownCloud Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
describe('OC.SetupChecks tests', function() {
@@ -22,123 +18,6 @@ describe('OC.SetupChecks tests', function() {
protocolStub.restore();
});
- describe('checkWebDAV', function() {
- it('should fail with another response status code than 201 or 207', function(done) {
- var async = OC.SetupChecks.checkWebDAV();
-
- suite.server.requests[0].respond(200);
-
- async.done(function( data, s, x ){
- expect(data).toEqual([{
- msg: 'Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken.',
- type: OC.SetupChecks.MESSAGE_TYPE_ERROR
- }]);
- done();
- });
- });
-
- it('should return no error with a response status code of 207', function(done) {
- var async = OC.SetupChecks.checkWebDAV();
-
- suite.server.requests[0].respond(207);
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
- });
-
- it('should return no error with a response status code of 401', function(done) {
- var async = OC.SetupChecks.checkWebDAV();
-
- suite.server.requests[0].respond(401);
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
- });
- });
-
- describe('checkWellKnownUrl', function() {
- it('should fail with another response status code than 207', function(done) {
- var async = OC.SetupChecks.checkWellKnownUrl('/.well-known/caldav/', 'http://example.org/PLACEHOLDER', true);
-
- suite.server.requests[0].respond(200);
-
- async.done(function( data, s, x ){
- expect(data).toEqual([{
- msg: 'Your web server is not set up properly to resolve "/.well-known/caldav/". Further information can be found in our <a target="_blank" rel="noreferrer" href="http://example.org/admin-setup-well-known-URL">documentation</a>.',
- type: OC.SetupChecks.MESSAGE_TYPE_INFO
- }]);
- done();
- });
- });
-
- it('should return no error with a response status code of 207', function(done) {
- var async = OC.SetupChecks.checkWellKnownUrl('/.well-known/caldav/', 'http://example.org/PLACEHOLDER', true);
-
- suite.server.requests[0].respond(207);
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
- });
-
- it('should return no error when no check should be run', function(done) {
- var async = OC.SetupChecks.checkWellKnownUrl('/.well-known/caldav/', 'http://example.org/PLACEHOLDER', false);
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
- });
- });
-
- describe('checkDataProtected', function() {
-
- oc_dataURL = "data";
-
- it('should return an error if data directory is not protected', function(done) {
- var async = OC.SetupChecks.checkDataProtected();
-
- suite.server.requests[0].respond(200);
-
- async.done(function( data, s, x ){
- expect(data).toEqual([
- {
- msg: 'Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root.',
- type: OC.SetupChecks.MESSAGE_TYPE_ERROR
- }]);
- done();
- });
- });
-
- it('should not return an error if data directory is protected', function(done) {
- var async = OC.SetupChecks.checkDataProtected();
-
- suite.server.requests[0].respond(403);
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
- });
-
- it('should return an error if data directory is a boolean', function(done) {
-
- oc_dataURL = false;
-
- var async = OC.SetupChecks.checkDataProtected();
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
- });
- });
-
describe('checkSetup', function() {
it('should return an error if server has no internet connection', function(done) {
var async = OC.SetupChecks.checkSetup();
@@ -149,24 +28,25 @@ describe('OC.SetupChecks tests', function() {
'Content-Type': 'application/json'
},
JSON.stringify({
- isUrandomAvailable: true,
- serverHasInternetConnection: false,
- memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance',
- forwardedForHeadersWorking: true,
- isCorrectMemcachedPHPModuleInstalled: true,
- hasPassedCodeIntegrityCheck: true,
+ generic: {
+ network: {
+ "Internet connectivity": {
+ severity: "warning",
+ description: 'This server has no working internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the internet to enjoy all features.',
+ linkToDoc: null
+ }
+ },
+ },
})
);
async.done(function( data, s, x ){
expect(data).toEqual([
{
- msg: 'This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features.',
+ msg: 'This server has no working internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the internet to enjoy all features.',
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
- }, {
- msg: 'No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target="_blank" rel="noreferrer" href="https://doc.owncloud.org/server/go.php?to=admin-performance">documentation</a>.',
- type: OC.SetupChecks.MESSAGE_TYPE_INFO
- }]);
+ },
+ ]);
done();
});
});
@@ -180,25 +60,25 @@ describe('OC.SetupChecks tests', function() {
'Content-Type': 'application/json'
},
JSON.stringify({
- isUrandomAvailable: true,
- serverHasInternetConnection: false,
- memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance',
- forwardedForHeadersWorking: true,
- isCorrectMemcachedPHPModuleInstalled: true,
- hasPassedCodeIntegrityCheck: true,
+ generic: {
+ network: {
+ "Internet connectivity": {
+ severity: "warning",
+ description: 'This server has no working internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the internet to enjoy all features.',
+ linkToDoc: null
+ }
+ },
+ },
})
);
async.done(function( data, s, x ){
expect(data).toEqual([
{
- msg: 'This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features.',
+ msg: 'This server has no working internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the internet to enjoy all features.',
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
},
- {
- msg: 'No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target="_blank" rel="noreferrer" href="https://doc.owncloud.org/server/go.php?to=admin-performance">documentation</a>.',
- type: OC.SetupChecks.MESSAGE_TYPE_INFO
- }]);
+ ]);
done();
});
});
@@ -212,19 +92,22 @@ describe('OC.SetupChecks tests', function() {
'Content-Type': 'application/json',
},
JSON.stringify({
- isUrandomAvailable: true,
- serverHasInternetConnection: false,
- isMemcacheConfigured: true,
- forwardedForHeadersWorking: true,
- isCorrectMemcachedPHPModuleInstalled: true,
- hasPassedCodeIntegrityCheck: true,
+ generic: {
+ network: {
+ "Internet connectivity": {
+ severity: "warning",
+ description: 'This server has no working internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the internet to enjoy all features.',
+ linkToDoc: null
+ }
+ },
+ },
})
);
async.done(function( data, s, x ){
expect(data).toEqual([
{
- msg: 'This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features.',
+ msg: 'This server has no working internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the internet to enjoy all features.',
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
}
]);
@@ -232,7 +115,7 @@ describe('OC.SetupChecks tests', function() {
});
});
- it('should return an error if /dev/urandom is not accessible', function(done) {
+ it('should return a warning if the memory limit is below the recommended value', function(done) {
var async = OC.SetupChecks.checkSetup();
suite.server.requests[0].respond(
@@ -241,54 +124,60 @@ describe('OC.SetupChecks tests', function() {
'Content-Type': 'application/json',
},
JSON.stringify({
- isUrandomAvailable: false,
- securityDocs: 'https://docs.owncloud.org/myDocs.html',
- serverHasInternetConnection: true,
- isMemcacheConfigured: true,
- forwardedForHeadersWorking: true,
- isCorrectMemcachedPHPModuleInstalled: true,
- hasPassedCodeIntegrityCheck: true,
+ generic: {
+ network: {
+ "Internet connectivity": {
+ severity: "success",
+ description: null,
+ linkToDoc: null
+ }
+ },
+ php: {
+ "Internet connectivity": {
+ severity: "success",
+ description: null,
+ linkToDoc: null
+ },
+ "PHP memory limit": {
+ severity: "error",
+ description: "The PHP memory limit is below the recommended value of 512MB.",
+ linkToDoc: null
+ },
+ },
+ },
})
);
async.done(function( data, s, x ){
expect(data).toEqual([{
- msg: '/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target="_blank" rel="noreferrer" href="https://docs.owncloud.org/myDocs.html">documentation</a>.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
+ msg: 'The PHP memory limit is below the recommended value of 512MB.',
+ type: OC.SetupChecks.MESSAGE_TYPE_ERROR
}]);
done();
});
});
- it('should return an error if the wrong memcache PHP module is installed', function(done) {
+ it('should return an error if the response has no statuscode 200', function(done) {
var async = OC.SetupChecks.checkSetup();
suite.server.requests[0].respond(
- 200,
+ 500,
{
- 'Content-Type': 'application/json',
+ 'Content-Type': 'application/json'
},
- JSON.stringify({
- isUrandomAvailable: true,
- securityDocs: 'https://docs.owncloud.org/myDocs.html',
- serverHasInternetConnection: true,
- isMemcacheConfigured: true,
- forwardedForHeadersWorking: true,
- isCorrectMemcachedPHPModuleInstalled: false,
- hasPassedCodeIntegrityCheck: true,
- })
+ JSON.stringify({data: {serverHasInternetConnectionProblems: true}})
);
async.done(function( data, s, x ){
expect(data).toEqual([{
- msg: 'Memcached is configured as distributed cache, but the wrong PHP module "memcache" is installed. \\OC\\Memcache\\Memcached only supports "memcached" and not "memcache". See the <a target="_blank" rel="noreferrer" href="https://code.google.com/p/memcached/wiki/PHPClientComparison">memcached wiki about both modules</a>.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
+ msg: 'Error occurred while checking server setup',
+ type: OC.SetupChecks.MESSAGE_TYPE_ERROR
}]);
done();
});
});
- it('should return an error if the forwarded for headers are not working', function(done) {
+ it('should return an error if the php version is no longer supported', function(done) {
var async = OC.SetupChecks.checkSetup();
suite.server.requests[0].respond(
@@ -297,46 +186,35 @@ describe('OC.SetupChecks tests', function() {
'Content-Type': 'application/json',
},
JSON.stringify({
- isUrandomAvailable: true,
- serverHasInternetConnection: true,
- isMemcacheConfigured: true,
- forwardedForHeadersWorking: false,
- reverseProxyDocs: 'https://docs.owncloud.org/foo/bar.html',
- isCorrectMemcachedPHPModuleInstalled: true,
- hasPassedCodeIntegrityCheck: true,
+ generic: {
+ network: {
+ "Internet connectivity": {
+ severity: "success",
+ description: null,
+ linkToDoc: null
+ }
+ },
+ security: {
+ "Checking for PHP version": {
+ severity: "warning",
+ description: "You are currently running PHP 8.0.30. PHP 8.0 is now deprecated in Nextcloud 27. Nextcloud 28 may require at least PHP 8.1. Please upgrade to one of the officially supported PHP versions provided by the PHP Group as soon as possible.",
+ linkToDoc: "https://secure.php.net/supported-versions.php"
+ }
+ },
+ },
})
);
async.done(function( data, s, x ){
expect(data).toEqual([{
- msg: 'The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a target="_blank" rel="noreferrer" href="https://docs.owncloud.org/foo/bar.html">documentation</a>.',
+ msg: 'You are currently running PHP 8.0.30. PHP 8.0 is now deprecated in Nextcloud 27. Nextcloud 28 may require at least PHP 8.1. Please upgrade to one of the officially supported PHP versions provided by the PHP Group as soon as possible. For more details see the <a target="_blank" rel="noreferrer noopener" class="external" href="https://secure.php.net/supported-versions.php">documentation ↗</a>.',
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
}]);
done();
});
});
- it('should return an error if the response has no statuscode 200', function(done) {
- var async = OC.SetupChecks.checkSetup();
-
- suite.server.requests[0].respond(
- 500,
- {
- 'Content-Type': 'application/json'
- },
- JSON.stringify({data: {serverHasInternetConnection: false}})
- );
-
- async.done(function( data, s, x ){
- expect(data).toEqual([{
- msg: 'Error occurred while checking server setup',
- type: OC.SetupChecks.MESSAGE_TYPE_ERROR
- }]);
- done();
- });
- });
-
- it('should return an error if the php version is no longer supported', function(done) {
+ it('should not return an error if the protocol is http and the server generates http links', function(done) {
var async = OC.SetupChecks.checkSetup();
suite.server.requests[0].respond(
@@ -345,337 +223,59 @@ describe('OC.SetupChecks tests', function() {
'Content-Type': 'application/json',
},
JSON.stringify({
- isUrandomAvailable: true,
- securityDocs: 'https://docs.owncloud.org/myDocs.html',
- serverHasInternetConnection: true,
- isMemcacheConfigured: true,
- forwardedForHeadersWorking: true,
- phpSupported: {eol: true, version: '5.4.0'},
- isCorrectMemcachedPHPModuleInstalled: true,
- hasPassedCodeIntegrityCheck: true,
+ generic: {
+ network: {
+ "Internet connectivity": {
+ severity: "success",
+ description: null,
+ linkToDoc: null
+ }
+ },
+ },
})
);
async.done(function( data, s, x ){
- expect(data).toEqual([{
- msg: 'You are currently running PHP 5.4.0. We encourage you to upgrade your PHP version to take advantage of <a target="_blank" rel="noreferrer" href="https://secure.php.net/supported-versions.php">performance and security updates provided by the PHP Group</a> as soon as your distribution supports it.',
- type: OC.SetupChecks.MESSAGE_TYPE_INFO
- }]);
- done();
- });
- });
- });
-
- describe('checkGeneric', function() {
- it('should return an error if the response has no statuscode 200', function(done) {
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(
- 500,
- {
- 'Content-Type': 'application/json'
- }
- );
-
- async.done(function( data, s, x ){
- expect(data).toEqual([{
- msg: 'Error occurred while checking server setup',
- type: OC.SetupChecks.MESSAGE_TYPE_ERROR
- },{
- msg: 'Error occurred while checking server setup',
- type: OC.SetupChecks.MESSAGE_TYPE_ERROR
- }]);
+ expect(data).toEqual([]);
done();
});
});
- it('should return all errors if all headers are missing', function(done) {
- protocolStub.returns('https');
- var async = OC.SetupChecks.checkGeneric();
+ it('should return an info if there is no default phone region', function(done) {
+ var async = OC.SetupChecks.checkSetup();
suite.server.requests[0].respond(
200,
{
'Content-Type': 'application/json',
- 'Strict-Transport-Security': 'max-age=15768000'
- }
- );
-
- async.done(function( data, s, x ){
- expect(data).toEqual([
- {
- msg: 'The "X-XSS-Protection" HTTP header is not configured to equal to "1; mode=block". This is a potential security or privacy risk and we recommend adjusting this setting.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
- }, {
- msg: 'The "X-Content-Type-Options" HTTP header is not configured to equal to "nosniff". This is a potential security or privacy risk and we recommend adjusting this setting.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
- }, {
- msg: 'The "X-Robots-Tag" HTTP header is not configured to equal to "none". This is a potential security or privacy risk and we recommend adjusting this setting.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
-
- }, {
- msg: 'The "X-Frame-Options" HTTP header is not configured to equal to "SAMEORIGIN". This is a potential security or privacy risk and we recommend adjusting this setting.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
- }, {
- msg: 'The "X-Download-Options" HTTP header is not configured to equal to "noopen". This is a potential security or privacy risk and we recommend adjusting this setting.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
- }, {
- msg: 'The "X-Permitted-Cross-Domain-Policies" HTTP header is not configured to equal to "none". This is a potential security or privacy risk and we recommend adjusting this setting.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
},
- ]);
- done();
- });
- });
-
- it('should return only some errors if just some headers are missing', function(done) {
- protocolStub.returns('https');
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(
- 200,
- {
- 'X-Robots-Tag': 'none',
- 'X-Frame-Options': 'SAMEORIGIN',
- 'Strict-Transport-Security': 'max-age=15768000;preload',
- 'X-Download-Options': 'noopen',
- 'X-Permitted-Cross-Domain-Policies': 'none',
- }
+ JSON.stringify({
+ generic: {
+ network: {
+ "Internet connectivity": {
+ severity: "success",
+ description: null,
+ linkToDoc: null
+ }
+ },
+ config: {
+ "Checking for default phone region": {
+ severity: "info",
+ description: "Your installation has no default phone region set. This is required to validate phone numbers in the profile settings without a country code. To allow numbers without a country code, please add \"default_phone_region\" with the respective ISO 3166-1 code of the region to your config file.",
+ linkToDoc: "https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements"
+ },
+ },
+ },
+ })
);
async.done(function( data, s, x ){
expect(data).toEqual([{
- msg: 'The "X-XSS-Protection" HTTP header is not configured to equal to "1; mode=block". This is a potential security or privacy risk and we recommend adjusting this setting.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING,
- }, {
- msg: 'The "X-Content-Type-Options" HTTP header is not configured to equal to "nosniff". This is a potential security or privacy risk and we recommend adjusting this setting.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
+ msg: 'Your installation has no default phone region set. This is required to validate phone numbers in the profile settings without a country code. To allow numbers without a country code, please add &quot;default_phone_region&quot; with the respective ISO 3166-1 code of the region to your config file. For more details see the <a target="_blank" rel="noreferrer noopener" class="external" href="https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements">documentation ↗</a>.',
+ type: OC.SetupChecks.MESSAGE_TYPE_INFO
}]);
done();
});
});
-
- it('should return none errors if all headers are there', function(done) {
- protocolStub.returns('https');
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(
- 200,
- {
- 'X-XSS-Protection': '1; mode=block',
- 'X-Content-Type-Options': 'nosniff',
- 'X-Robots-Tag': 'none',
- 'X-Frame-Options': 'SAMEORIGIN',
- 'Strict-Transport-Security': 'max-age=15768000',
- 'X-Download-Options': 'noopen',
- 'X-Permitted-Cross-Domain-Policies': 'none',
- }
- );
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
- });
- });
-
- it('should return a SSL warning if HTTPS is not used', function(done) {
- protocolStub.returns('http');
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(200,
- {
- 'X-XSS-Protection': '1; mode=block',
- 'X-Content-Type-Options': 'nosniff',
- 'X-Robots-Tag': 'none',
- 'X-Frame-Options': 'SAMEORIGIN',
- 'X-Download-Options': 'noopen',
- 'X-Permitted-Cross-Domain-Policies': 'none',
- }
- );
-
- async.done(function( data, s, x ){
- expect(data).toEqual([{
- msg: 'You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href="#admin-tips">security tips</a>.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
- }]);
- done();
- });
- });
-
- it('should return an error if the response has no statuscode 200', function(done) {
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(
- 500,
- {
- 'Content-Type': 'application/json'
- },
- JSON.stringify({data: {serverHasInternetConnection: false}})
- );
- async.done(function( data, s, x ){
- expect(data).toEqual([{
- msg: 'Error occurred while checking server setup',
- type: OC.SetupChecks.MESSAGE_TYPE_ERROR
- }, {
- msg: 'Error occurred while checking server setup',
- type: OC.SetupChecks.MESSAGE_TYPE_ERROR
- }]);
- done();
- });
- });
-
- it('should return a SSL warning if SSL used without Strict-Transport-Security-Header', function(done) {
- protocolStub.returns('https');
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(200,
- {
- 'X-XSS-Protection': '1; mode=block',
- 'X-Content-Type-Options': 'nosniff',
- 'X-Robots-Tag': 'none',
- 'X-Frame-Options': 'SAMEORIGIN',
- 'X-Download-Options': 'noopen',
- 'X-Permitted-Cross-Domain-Policies': 'none',
- }
- );
-
- async.done(function( data, s, x ){
- expect(data).toEqual([{
- msg: 'The "Strict-Transport-Security" HTTP header is not configured to at least "15768000" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="#admin-tips" rel="noreferrer">security tips</a>.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
- }]);
- done();
- });
- });
-
- it('should return a SSL warning if SSL used with to small Strict-Transport-Security-Header', function(done) {
- protocolStub.returns('https');
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(200,
- {
- 'Strict-Transport-Security': 'max-age=15767999',
- 'X-XSS-Protection': '1; mode=block',
- 'X-Content-Type-Options': 'nosniff',
- 'X-Robots-Tag': 'none',
- 'X-Frame-Options': 'SAMEORIGIN',
- 'X-Download-Options': 'noopen',
- 'X-Permitted-Cross-Domain-Policies': 'none',
- }
- );
-
- async.done(function( data, s, x ){
- expect(data).toEqual([{
- msg: 'The "Strict-Transport-Security" HTTP header is not configured to at least "15768000" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="#admin-tips" rel="noreferrer">security tips</a>.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
- }]);
- done();
- });
- });
-
- it('should return a SSL warning if SSL used with to a bogus Strict-Transport-Security-Header', function(done) {
- protocolStub.returns('https');
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(200,
- {
- 'Strict-Transport-Security': 'iAmABogusHeader342',
- 'X-XSS-Protection': '1; mode=block',
- 'X-Content-Type-Options': 'nosniff',
- 'X-Robots-Tag': 'none',
- 'X-Frame-Options': 'SAMEORIGIN',
- 'X-Download-Options': 'noopen',
- 'X-Permitted-Cross-Domain-Policies': 'none',
- }
- );
-
- async.done(function( data, s, x ){
- expect(data).toEqual([{
- msg: 'The "Strict-Transport-Security" HTTP header is not configured to at least "15768000" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="#admin-tips" rel="noreferrer">security tips</a>.',
- type: OC.SetupChecks.MESSAGE_TYPE_WARNING
- }]);
- done();
- });
- });
-
- it('should return no SSL warning if SSL used with to exact the minimum Strict-Transport-Security-Header', function(done) {
- protocolStub.returns('https');
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(200, {
- 'Strict-Transport-Security': 'max-age=15768000',
- 'X-XSS-Protection': '1; mode=block',
- 'X-Content-Type-Options': 'nosniff',
- 'X-Robots-Tag': 'none',
- 'X-Frame-Options': 'SAMEORIGIN',
- 'X-Download-Options': 'noopen',
- 'X-Permitted-Cross-Domain-Policies': 'none',
- });
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
- });
-
- it('should return no SSL warning if SSL used with to more than the minimum Strict-Transport-Security-Header', function(done) {
- protocolStub.returns('https');
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(200, {
- 'Strict-Transport-Security': 'max-age=99999999',
- 'X-XSS-Protection': '1; mode=block',
- 'X-Content-Type-Options': 'nosniff',
- 'X-Robots-Tag': 'none',
- 'X-Frame-Options': 'SAMEORIGIN',
- 'X-Download-Options': 'noopen',
- 'X-Permitted-Cross-Domain-Policies': 'none',
- });
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
- });
-
- it('should return no SSL warning if SSL used with to more than the minimum Strict-Transport-Security-Header and includeSubDomains parameter', function(done) {
- protocolStub.returns('https');
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(200, {
- 'Strict-Transport-Security': 'max-age=99999999; includeSubDomains',
- 'X-XSS-Protection': '1; mode=block',
- 'X-Content-Type-Options': 'nosniff',
- 'X-Robots-Tag': 'none',
- 'X-Frame-Options': 'SAMEORIGIN',
- 'X-Download-Options': 'noopen',
- 'X-Permitted-Cross-Domain-Policies': 'none',
- });
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
- });
-
- it('should return no SSL warning if SSL used with to more than the minimum Strict-Transport-Security-Header and includeSubDomains and preload parameter', function(done) {
- protocolStub.returns('https');
- var async = OC.SetupChecks.checkGeneric();
-
- suite.server.requests[0].respond(200, {
- 'Strict-Transport-Security': 'max-age=99999999; preload; includeSubDomains',
- 'X-XSS-Protection': '1; mode=block',
- 'X-Content-Type-Options': 'nosniff',
- 'X-Robots-Tag': 'none',
- 'X-Frame-Options': 'SAMEORIGIN',
- 'X-Download-Options': 'noopen',
- 'X-Permitted-Cross-Domain-Policies': 'none',
- });
-
- async.done(function( data, s, x ){
- expect(data).toEqual([]);
- done();
- });
});
});
diff --git a/core/js/tests/specs/shareSpec.js b/core/js/tests/specs/shareSpec.js
deleted file mode 100644
index 5c76ea600b8..00000000000
--- a/core/js/tests/specs/shareSpec.js
+++ /dev/null
@@ -1,243 +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/>.
-*
-*/
-
-/* global oc_appconfig */
-describe('OC.Share tests', function() {
- describe('markFileAsShared', function() {
- var $file;
- var tipsyStub;
-
- beforeEach(function() {
- tipsyStub = sinon.stub($.fn, 'tipsy');
- $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;
- tipsyStub.restore();
- });
- describe('displaying the share owner', function() {
- function checkOwner(input, output, title) {
- var $action;
-
- $file.attr('data-share-owner', input);
- OC.Share.markFileAsShared($file);
-
- $action = $file.find('.action-share>span');
- 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(tipsyStub.calledOnce).toEqual(true);
- tipsyStub.reset();
- }
-
- it('displays the local share owner as is', function() {
- checkOwner('User One', 'User One', null);
- });
- it('displays the user name part of a remote share owner', function() {
- checkOwner(
- 'User One@someserver.com',
- 'User One@…',
- 'User One@someserver.com'
- );
- checkOwner(
- 'User One@someserver.com/',
- 'User One@…',
- 'User One@someserver.com'
- );
- checkOwner(
- 'User One@someserver.com/root/of/owncloud',
- 'User One@…',
- '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',
- 'User One@example.com@someserver.com'
- );
- checkOwner(
- 'User One@example.com@someserver.com/',
- 'User One@example.com',
- 'User One@example.com@someserver.com'
- );
- checkOwner(
- 'User One@example.com@someserver.com/root/of/owncloud',
- 'User One@example.com',
- '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');
- 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');
- });
- });
-
- describe('displaying the recipoients', function() {
- function checkRecipients(input, output, title) {
- var $action;
-
- $file.attr('data-share-recipients', input);
- OC.Share.markFileAsShared($file, true);
-
- $action = $file.find('.action-share>span');
- 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(tipsyStub.calledOnce).toEqual(true);
- tipsyStub.reset();
- }
-
- it('displays the local share owner as is', function() {
- checkRecipients('User One', 'Shared with User One', null);
- });
- it('displays the user name part of a remote recipient', function() {
- checkRecipients(
- 'User One@someserver.com',
- 'Shared with User One@…',
- 'User One@someserver.com'
- );
- checkRecipients(
- 'User One@someserver.com/',
- 'Shared with User One@…',
- 'User One@someserver.com'
- );
- checkRecipients(
- 'User One@someserver.com/root/of/owncloud',
- 'Shared with User One@…',
- 'User One@someserver.com'
- );
- });
- it('displays the user name part with domain of a remote share owner', function() {
- checkRecipients(
- 'User One@example.com@someserver.com',
- 'Shared with User One@example.com',
- 'User One@example.com@someserver.com'
- );
- checkRecipients(
- 'User One@example.com@someserver.com/',
- 'Shared with User One@example.com',
- 'User One@example.com@someserver.com'
- );
- checkRecipients(
- 'User One@example.com@someserver.com/root/of/owncloud',
- 'Shared with User One@example.com',
- 'User One@example.com@someserver.com'
- );
- });
- it('display multiple remote recipients', function() {
- checkRecipients(
- 'One@someserver.com, two@otherserver.com',
- 'Shared with One@…, two@…',
- ['One@someserver.com', 'two@otherserver.com']
- );
- checkRecipients(
- 'One@someserver.com/, two@otherserver.com',
- 'Shared with One@…, two@…',
- ['One@someserver.com', 'two@otherserver.com']
- );
- checkRecipients(
- 'One@someserver.com/root/of/owncloud, two@otherserver.com',
- 'Shared with One@…, two@…',
- ['One@someserver.com', 'two@otherserver.com']
- );
- });
- it('display mixed recipients', function() {
- checkRecipients(
- 'One, two@otherserver.com',
- 'Shared with One, two@…',
- ['two@otherserver.com']
- );
- });
- });
- });
-});
-
diff --git a/core/js/tests/specs/sharedialogshareelistview.js b/core/js/tests/specs/sharedialogshareelistview.js
deleted file mode 100644
index cef97469753..00000000000
--- a/core/js/tests/specs/sharedialogshareelistview.js
+++ /dev/null
@@ -1,158 +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/>.
- *
- */
-
-/* global oc_appconfig */
-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;
-
- $('#testArea').append('<input id="mailNotificationEnabled" name="mailNotificationEnabled" type="hidden" value="yes">');
-
- 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,
- enforcePasswordForPublicLink: false,
- 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({
- linkShare: {isLinkShare: false}
- });
-
- 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('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'
- }]);
- 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('Checks edit box when 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'
- }]);
- 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);
- });
-
- it('shows cruds checkboxes when toggled', 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'
- }]);
- listView.render();
- listView.$el.find('a.showCruds').click();
- expect(listView.$el.find('li.cruds').hasClass('hidden')).toEqual(false);
- });
-
- it('sends notification to user when checkbox clicked', 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'
- }]);
- listView.render();
- var notificationStub = sinon.stub(listView.model, 'sendNotificationForShare');
- listView.$el.find("input[name='mailNotification']").click();
- expect(notificationStub.called).toEqual(true);
- notificationStub.restore();
- });
-
- });
-
-});
diff --git a/core/js/tests/specs/sharedialogviewSpec.js b/core/js/tests/specs/sharedialogviewSpec.js
deleted file mode 100644
index 23214a7fe86..00000000000
--- a/core/js/tests/specs/sharedialogviewSpec.js
+++ /dev/null
@@ -1,1064 +0,0 @@
-/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2015 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/>.
-*
-*/
-
-/* global oc_appconfig */
-describe('OC.Share.ShareDialogView', function() {
- var $container;
- var oldAppConfig;
- var autocompleteStub;
- var oldEnableAvatars;
- var avatarStub;
- var placeholderStub;
- var oldCurrentUser;
- var saveLinkShareStub;
-
- var fetchStub;
- var notificationStub;
-
- var configModel;
- var shareModel;
- var fileInfoModel;
- var dialog;
-
- beforeEach(function() {
- // horrible parameters
- $('#testArea').append('<input id="allowShareWithLink" type="hidden" value="yes">');
- $('#testArea').append('<input id="mailPublicNotificationEnabled" name="mailPublicNotificationEnabled" type="hidden" value="yes">');
- $container = $('#shareContainer');
- /* jshint camelcase:false */
- oldAppConfig = _.extend({}, oc_appconfig.core);
- oc_appconfig.core.enforcePasswordForPublicLink = false;
-
- fetchStub = sinon.stub(OC.Share.ShareItemModel.prototype, 'fetch');
- saveLinkShareStub = sinon.stub(OC.Share.ShareItemModel.prototype, 'saveLinkShare');
-
- 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
- };
- configModel = new OC.Share.ShareConfigModel({
- enforcePasswordForPublicLink: false,
- isResharingAllowed: true,
- enforcePasswordForPublicLink: false,
- isDefaultExpireDateEnabled: false,
- isDefaultExpireDateEnforced: false,
- defaultExpireDate: 7
- });
- shareModel = new OC.Share.ShareItemModel(attributes, {
- configModel: configModel,
- fileInfoModel: fileInfoModel
- });
- dialog = new OC.Share.ShareDialogView({
- configModel: configModel,
- model: shareModel
- });
-
- // required for proper event propagation when simulating clicks in some cases (jquery bugs)
- $('#testArea').append(dialog.$el);
-
- // triggers rendering
- shareModel.set({
- shares: [],
- linkShare: {isLinkShare: false}
- });
-
- autocompleteStub = sinon.stub($.fn, 'autocomplete', function() {
- // dummy container with the expected attributes
- if (!$(this).length) {
- // simulate the real autocomplete that returns
- // nothing at all when no element is specified
- // (and potentially break stuff)
- return null;
- }
- var $el = $('<div></div>').data('ui-autocomplete', {});
- return $el;
- });
-
- oldEnableAvatars = oc_config.enable_avatars;
- oc_config.enable_avatars = false;
- avatarStub = sinon.stub($.fn, 'avatar');
- placeholderStub = sinon.stub($.fn, 'imageplaceholder');
-
- oldCurrentUser = OC.currentUser;
- OC.currentUser = 'user0';
- });
- afterEach(function() {
- OC.currentUser = oldCurrentUser;
- /* jshint camelcase:false */
- oc_appconfig.core = oldAppConfig;
-
- dialog.remove();
- fetchStub.restore();
- saveLinkShareStub.restore();
-
- autocompleteStub.restore();
- avatarStub.restore();
- placeholderStub.restore();
- oc_config.enable_avatars = oldEnableAvatars;
- });
- describe('Share with link', function() {
- // TODO: test ajax calls
- // TODO: test password field visibility (whenever enforced or not)
- it('update password on focus out', function() {
- $('#allowShareWithLink').val('yes');
-
- dialog.model.set('linkShare', {
- isLinkShare: true
- });
- dialog.render();
-
- // Enable password, enter password and focusout
- dialog.$el.find('[name=showPassword]').click();
- dialog.$el.find('.linkPassText').focus();
- dialog.$el.find('.linkPassText').val('foo');
- dialog.$el.find('.linkPassText').focusout();
-
- expect(saveLinkShareStub.calledOnce).toEqual(true);
- expect(saveLinkShareStub.firstCall.args[0]).toEqual({
- password: 'foo'
- });
- });
- it('update password on enter', function() {
- $('#allowShareWithLink').val('yes');
-
- dialog.model.set('linkShare', {
- isLinkShare: true
- });
- dialog.render();
-
- // Toggle linkshare
- dialog.$el.find('.linkCheckbox').click();
-
- // Enable password and enter password
- dialog.$el.find('[name=showPassword]').click();
- dialog.$el.find('.linkPassText').focus();
- dialog.$el.find('.linkPassText').val('foo');
- dialog.$el.find('.linkPassText').trigger(new $.Event('keyup', {keyCode: 13}));
-
- expect(saveLinkShareStub.calledOnce).toEqual(true);
- expect(saveLinkShareStub.firstCall.args[0]).toEqual({
- password: 'foo'
- });
- });
- it('shows share with link checkbox when allowed', function() {
- $('#allowShareWithLink').val('yes');
-
- dialog.render();
-
- expect(dialog.$el.find('.linkCheckbox').length).toEqual(1);
- });
- it('does not show share with link checkbox when not allowed', function() {
- $('#allowShareWithLink').val('no');
-
- dialog.render();
-
- expect(dialog.$el.find('.linkCheckbox').length).toEqual(0);
- expect(dialog.$el.find('.shareWithField').length).toEqual(1);
- });
- it('shows populated link share when a link share exists', function() {
- // this is how the OC.Share class does it...
- var link = parent.location.protocol + '//' + location.host +
- OC.generateUrl('/s/') + 'tehtoken';
- shareModel.set('linkShare', {
- isLinkShare: true,
- token: 'tehtoken',
- link: link,
- expiration: '',
- permissions: OC.PERMISSION_READ,
- stime: 1403884258,
- });
-
- dialog.render();
-
- expect(dialog.$el.find('.linkCheckbox').prop('checked')).toEqual(true);
- expect(dialog.$el.find('.linkText').val()).toEqual(link);
- });
- it('autofocus link text when clicked', function() {
- $('#allowShareWithLink').val('yes');
-
- dialog.model.set('linkShare', {
- isLinkShare: true
- });
- dialog.render();
-
- var focusStub = sinon.stub($.fn, 'focus');
- var selectStub = sinon.stub($.fn, 'select');
- dialog.$el.find('.linkText').click();
-
- expect(focusStub.calledOnce).toEqual(true);
- expect(selectStub.calledOnce).toEqual(true);
-
- focusStub.restore();
- selectStub.restore();
- });
- describe('password', function() {
- var slideToggleStub;
-
- beforeEach(function() {
- $('#allowShareWithLink').val('yes');
- configModel.set({
- enforcePasswordForPublicLink: false
- });
-
- slideToggleStub = sinon.stub($.fn, 'slideToggle');
- });
- afterEach(function() {
- slideToggleStub.restore();
- });
-
- it('enforced but toggled does not fire request', function() {
- configModel.set('enforcePasswordForPublicLink', true);
- dialog.render();
-
- dialog.$el.find('.linkCheckbox').click();
-
- // The password linkPass field is shown (slideToggle is called).
- // No request is made yet
- expect(slideToggleStub.callCount).toEqual(1);
- expect(slideToggleStub.getCall(0).thisValue.eq(0).attr('id')).toEqual('linkPass');
- expect(fakeServer.requests.length).toEqual(0);
-
- // Now untoggle share by link
- dialog.$el.find('.linkCheckbox').click();
- dialog.render();
-
- // Password field disappears and no ajax requests have been made
- expect(fakeServer.requests.length).toEqual(0);
- expect(slideToggleStub.callCount).toEqual(2);
- expect(slideToggleStub.getCall(1).thisValue.eq(0).attr('id')).toEqual('linkPass');
- });
- });
- describe('expiration date', function() {
- var shareData;
- var shareItem;
- var clock;
- var expectedMinDate;
-
- beforeEach(function() {
- // pick a fake date
- clock = sinon.useFakeTimers(new Date(2014, 0, 20, 14, 0, 0).getTime());
- expectedMinDate = new Date(2014, 0, 21, 14, 0, 0);
-
- configModel.set({
- enforcePasswordForPublicLink: false,
- isDefaultExpireDateEnabled: false,
- isDefaultExpireDateEnforced: false,
- defaultExpireDate: 7
- });
-
- shareModel.set('linkShare', {
- isLinkShare: true,
- token: 'tehtoken',
- permissions: OC.PERMISSION_READ,
- expiration: null
- });
- });
- afterEach(function() {
- clock.restore();
- });
-
- it('does not check expiration date checkbox when no date was set', function() {
- shareModel.get('linkShare').expiration = null;
- dialog.render();
-
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('checked')).toEqual(false);
- expect(dialog.$el.find('.datepicker').val()).toEqual('');
- });
- it('does not check expiration date checkbox for new share', function() {
- dialog.render();
-
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('checked')).toEqual(false);
- expect(dialog.$el.find('.datepicker').val()).toEqual('');
- });
- it('checks expiration date checkbox and populates field when expiration date was set', function() {
- shareModel.get('linkShare').expiration = '2014-02-01 00:00:00';
- dialog.render();
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('checked')).toEqual(true);
- expect(dialog.$el.find('.datepicker').val()).toEqual('01-02-2014');
- });
- it('sets default date when default date setting is enabled', function() {
- configModel.set('isDefaultExpireDateEnabled', true);
- dialog.render();
- dialog.$el.find('.linkCheckbox').click();
- // here fetch would be called and the server returns the expiration date
- shareModel.get('linkShare').expiration = '2014-1-27 00:00:00';
- dialog.render();
-
- // enabled by default
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('checked')).toEqual(true);
- expect(dialog.$el.find('.datepicker').val()).toEqual('27-01-2014');
-
- // disabling is allowed
- dialog.$el.find('[name=expirationCheckbox]').click();
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('checked')).toEqual(false);
- });
- it('enforces default date when enforced date setting is enabled', function() {
- configModel.set({
- isDefaultExpireDateEnabled: true,
- isDefaultExpireDateEnforced: true
- });
- dialog.render();
- dialog.$el.find('.linkCheckbox').click();
- // here fetch would be called and the server returns the expiration date
- shareModel.get('linkShare').expiration = '2014-1-27 00:00:00';
- dialog.render();
-
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('checked')).toEqual(true);
- expect(dialog.$el.find('.datepicker').val()).toEqual('27-01-2014');
-
- // disabling is not allowed
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('disabled')).toEqual(true);
- dialog.$el.find('[name=expirationCheckbox]').click();
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('checked')).toEqual(true);
- });
- it('enforces default date when enforced date setting is enabled and password is enforced', function() {
- configModel.set({
- enforcePasswordForPublicLink: true,
- isDefaultExpireDateEnabled: true,
- isDefaultExpireDateEnforced: true
- });
- dialog.render();
- dialog.$el.find('.linkCheckbox').click();
- // here fetch would be called and the server returns the expiration date
- shareModel.get('linkShare').expiration = '2014-1-27 00:00:00';
- dialog.render();
-
- //Enter password
- dialog.$el.find('.linkPassText').val('foo');
- dialog.$el.find('.linkPassText').trigger(new $.Event('keyup', {keyCode: 13}));
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({data: {token: 'xyz'}, status: 'success'})
- );
-
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('checked')).toEqual(true);
- expect(dialog.$el.find('.datepicker').val()).toEqual('27-01-2014');
-
- // disabling is not allowed
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('disabled')).toEqual(true);
- dialog.$el.find('[name=expirationCheckbox]').click();
- expect(dialog.$el.find('[name=expirationCheckbox]').prop('checked')).toEqual(true);
- });
- it('sets picker minDate to today and no maxDate by default', function() {
- dialog.render();
- dialog.$el.find('.linkCheckbox').click();
- dialog.$el.find('[name=expirationCheckbox]').click();
- expect($.datepicker._defaults.minDate).toEqual(expectedMinDate);
- expect($.datepicker._defaults.maxDate).toEqual(null);
- });
- it('limits the date range to X days after share time when enforced', function() {
- configModel.set({
- isDefaultExpireDateEnabled: true,
- isDefaultExpireDateEnforced: true
- });
- dialog.render();
- dialog.$el.find('.linkCheckbox').click();
- expect($.datepicker._defaults.minDate).toEqual(expectedMinDate);
- expect($.datepicker._defaults.maxDate).toEqual(new Date(2014, 0, 27, 0, 0, 0, 0));
- });
- it('limits the date range to X days after share time when enforced, even when redisplayed the next days', function() {
- // item exists, was created two days ago
- var shareItem = shareModel.get('linkShare');
- shareItem.expiration = '2014-1-27';
- // share time has time component but must be stripped later
- shareItem.stime = new Date(2014, 0, 20, 11, 0, 25).getTime() / 1000;
- configModel.set({
- isDefaultExpireDateEnabled: true,
- isDefaultExpireDateEnforced: true
- });
- dialog.render();
- expect($.datepicker._defaults.minDate).toEqual(expectedMinDate);
- expect($.datepicker._defaults.maxDate).toEqual(new Date(2014, 0, 27, 0, 0, 0, 0));
- });
- });
- describe('send link by email', function() {
- var sendEmailPrivateLinkStub;
- var clock;
-
- beforeEach(function() {
- configModel.set({
- isMailPublicNotificationEnabled: true
- });
-
- shareModel.set('linkShare', {
- isLinkShare: true,
- token: 'tehtoken',
- permissions: OC.PERMISSION_READ,
- expiration: null
- });
-
- sendEmailPrivateLinkStub = sinon.stub(dialog.model, "sendEmailPrivateLink");
- clock = sinon.useFakeTimers();
- });
- afterEach(function() {
- sendEmailPrivateLinkStub.restore();
- clock.restore();
- });
-
- it('displays form when sending emails is enabled', function() {
- $('input[name=mailPublicNotificationEnabled]').val('yes');
- dialog.render();
- expect(dialog.$('.emailPrivateLinkForm').length).toEqual(1);
- });
- it('form not rendered when sending emails is disabled', function() {
- $('input[name=mailPublicNotificationEnabled]').val('no');
- dialog.render();
- expect(dialog.$('.emailPrivateLinkForm').length).toEqual(0);
- });
- it('input cleared on success', function() {
- var defer = $.Deferred();
- sendEmailPrivateLinkStub.returns(defer.promise());
-
- $('input[name=mailPublicNotificationEnabled]').val('yes');
- dialog.render();
-
- dialog.$el.find('.emailPrivateLinkForm .emailField').val('a@b.c');
- dialog.$el.find('.emailPrivateLinkForm').trigger('submit');
-
- expect(sendEmailPrivateLinkStub.callCount).toEqual(1);
- expect(dialog.$el.find('.emailPrivateLinkForm .emailField').val()).toEqual('Sending ...');
-
- defer.resolve();
- expect(dialog.$el.find('.emailPrivateLinkForm .emailField').val()).toEqual('Email sent');
-
- clock.tick(2000);
- expect(dialog.$el.find('.emailPrivateLinkForm .emailField').val()).toEqual('');
- });
- it('input not cleared on failure', function() {
- var defer = $.Deferred();
- sendEmailPrivateLinkStub.returns(defer.promise());
-
- $('input[name=mailPublicNotificationEnabled]').val('yes');
- dialog.render();
-
- dialog.$el.find('.emailPrivateLinkForm .emailField').val('a@b.c');
- dialog.$el.find('.emailPrivateLinkForm').trigger('submit');
-
- expect(sendEmailPrivateLinkStub.callCount).toEqual(1);
- expect(dialog.$el.find('.emailPrivateLinkForm .emailField').val()).toEqual('Sending ...');
-
- defer.reject();
- expect(dialog.$el.find('.emailPrivateLinkForm .emailField').val()).toEqual('a@b.c');
- });
- });
- });
- describe('check for avatar', function() {
- beforeEach(function() {
- shareModel.set({
- reshare: {
- share_type: OC.Share.SHARE_TYPE_USER,
- uid_owner: 'owner',
- displayname_owner: 'Owner',
- permissions: 31
- },
- shares: [{
- id: 100,
- item_source: 123,
- permissions: 31,
- share_type: OC.Share.SHARE_TYPE_USER,
- share_with: 'user1',
- share_with_displayname: 'User One'
- },{
- id: 101,
- item_source: 123,
- permissions: 31,
- share_type: OC.Share.SHARE_TYPE_GROUP,
- share_with: 'group',
- share_with_displayname: 'group'
- },{
- id: 102,
- item_source: 123,
- permissions: 31,
- share_type: OC.Share.SHARE_TYPE_REMOTE,
- share_with: 'foo@bar.com/baz',
- share_with_displayname: 'foo@bar.com/baz'
-
- }]
- });
- });
-
- describe('avatars enabled', function() {
- beforeEach(function() {
- oc_config.enable_avatars = true;
- avatarStub.reset();
- dialog.render();
- });
-
- afterEach(function() {
- oc_config.enable_avatars = false;
- });
-
- it('test correct function calls', function() {
- expect(avatarStub.calledTwice).toEqual(true);
- expect(placeholderStub.calledTwice).toEqual(true);
- expect(dialog.$('.shareWithList').children().length).toEqual(3);
- expect(dialog.$('.avatar').length).toEqual(4);
- });
-
- it('test avatar owner', function() {
- var args = avatarStub.getCall(0).args;
- expect(args.length).toEqual(2);
- expect(args[0]).toEqual('owner');
- });
-
- it('test avatar user', function() {
- var args = avatarStub.getCall(1).args;
- expect(args.length).toEqual(2);
- expect(args[0]).toEqual('user1');
- });
-
- it('test avatar for groups', function() {
- var args = placeholderStub.getCall(0).args;
- expect(args.length).toEqual(1);
- expect(args[0]).toEqual('group ' + OC.Share.SHARE_TYPE_GROUP);
- });
-
- it('test avatar for remotes', function() {
- var args = placeholderStub.getCall(1).args;
- expect(args.length).toEqual(1);
- expect(args[0]).toEqual('foo@bar.com/baz ' + OC.Share.SHARE_TYPE_REMOTE);
- });
- });
-
- describe('avatars disabled', function() {
- beforeEach(function() {
- dialog.render();
- });
-
- it('no avatar classes', function() {
- expect($('.avatar').length).toEqual(0);
- expect(avatarStub.callCount).toEqual(0);
- expect(placeholderStub.callCount).toEqual(0);
- });
- });
- });
- describe('remote sharing', function() {
- it('shows remote share info when allowed', function() {
- configModel.set({
- isRemoteShareAllowed: true
- });
- dialog.render();
- expect(dialog.$el.find('.shareWithRemoteInfo').length).toEqual(1);
- });
- it('does not show remote share info when not allowed', function() {
- configModel.set({
- isRemoteShareAllowed: false
- });
- dialog.render();
- expect(dialog.$el.find('.shareWithRemoteInfo').length).toEqual(0);
- });
- });
- 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);
- var jsonData = JSON.stringify({
- 'ocs' : {
- 'meta' : {
- 'status' : 'success',
- 'statuscode' : 100,
- 'message' : null
- },
- 'data' : {
- 'exact' : {
- 'users' : [],
- 'groups' : [],
- 'remotes': []
- },
- 'users' : [{'label': 'bob', 'value': {'shareType': 0, 'shareWith': 'test'}}],
- 'groups' : [],
- 'remotes': []
- }
- }
- });
- fakeServer.requests[0].respond(
- 200,
- {'Content-Type': 'application/json'},
- jsonData
- );
- expect(response.calledWithExactly(JSON.parse(jsonData).ocs.data.users)).toEqual(true);
- expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
- });
-
- describe('filter out', function() {
- it('the current user', function () {
- dialog.render();
- var response = sinon.stub();
- dialog.autocompleteHandler({term: 'bob'}, response);
- var jsonData = JSON.stringify({
- 'ocs': {
- 'meta': {
- 'status': 'success',
- 'statuscode': 100,
- 'message': null
- },
- 'data': {
- 'exact': {
- 'users': [],
- 'groups': [],
- 'remotes': []
- },
- 'users': [
- {
- 'label': 'bob',
- 'value': {
- 'shareType': 0,
- 'shareWith': OC.currentUser
- }
- },
- {
- 'label': 'bobby',
- 'value': {
- 'shareType': 0,
- 'shareWith': 'imbob'
- }
- }
- ],
- 'groups': [],
- 'remotes': []
- }
- }
- });
- fakeServer.requests[0].respond(
- 200,
- {'Content-Type': 'application/json'},
- jsonData
- );
- expect(response.calledWithExactly([{
- 'label': 'bobby',
- 'value': {'shareType': 0, 'shareWith': 'imbob'}
- }])).toEqual(true);
- expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
- });
-
- it('the share owner', function () {
- shareModel.set({
- reshare: {
- uid_owner: 'user1'
- },
- shares: [],
- permissions: OC.PERMISSION_READ
- });
-
- dialog.render();
- var response = sinon.stub();
- dialog.autocompleteHandler({term: 'bob'}, response);
- var jsonData = JSON.stringify({
- 'ocs': {
- 'meta': {
- 'status': 'success',
- 'statuscode': 100,
- 'message': null
- },
- 'data': {
- 'exact': {
- 'users': [],
- 'groups': [],
- 'remotes': []
- },
- 'users': [
- {
- 'label': 'bob',
- 'value': {
- 'shareType': 0,
- 'shareWith': 'user1'
- }
- },
- {
- 'label': 'bobby',
- 'value': {
- 'shareType': 0,
- 'shareWith': 'imbob'
- }
- }
- ],
- 'groups': [],
- 'remotes': []
- }
- }
- });
- fakeServer.requests[0].respond(
- 200,
- {'Content-Type': 'application/json'},
- jsonData
- );
- expect(response.calledWithExactly([{
- 'label': 'bobby',
- 'value': {'shareType': 0, 'shareWith': 'imbob'}
- }])).toEqual(true);
- expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
- });
-
- describe('already shared with', function () {
- beforeEach(function() {
- shareModel.set({
- reshare: {},
- shares: [{
- id: 100,
- item_source: 123,
- permissions: 31,
- share_type: OC.Share.SHARE_TYPE_USER,
- share_with: 'user1',
- share_with_displayname: 'User One'
- },{
- id: 101,
- item_source: 123,
- permissions: 31,
- share_type: OC.Share.SHARE_TYPE_GROUP,
- share_with: 'group',
- share_with_displayname: 'group'
- },{
- id: 102,
- item_source: 123,
- permissions: 31,
- share_type: OC.Share.SHARE_TYPE_REMOTE,
- share_with: 'foo@bar.com/baz',
- share_with_displayname: 'foo@bar.com/baz'
-
- }]
- });
- });
-
- it('users', function () {
- dialog.render();
- var response = sinon.stub();
- dialog.autocompleteHandler({term: 'bob'}, response);
- var jsonData = JSON.stringify({
- 'ocs': {
- 'meta': {
- 'status': 'success',
- 'statuscode': 100,
- 'message': null
- },
- 'data': {
- 'exact': {
- 'users': [],
- 'groups': [],
- 'remotes': []
- },
- 'users': [
- {
- 'label': 'bob',
- 'value': {
- 'shareType': OC.Share.SHARE_TYPE_USER,
- 'shareWith': 'user1'
- }
- },
- {
- 'label': 'bobby',
- 'value': {
- 'shareType': OC.Share.SHARE_TYPE_USER,
- 'shareWith': 'imbob'
- }
- }
- ],
- 'groups': [],
- 'remotes': []
- }
- }
- });
- fakeServer.requests[0].respond(
- 200,
- {'Content-Type': 'application/json'},
- jsonData
- );
- expect(response.calledWithExactly([{
- 'label': 'bobby',
- 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'}
- }])).toEqual(true);
- expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
- });
-
- it('groups', function () {
- dialog.render();
- var response = sinon.stub();
- dialog.autocompleteHandler({term: 'group'}, response);
- var jsonData = JSON.stringify({
- 'ocs': {
- 'meta': {
- 'status': 'success',
- 'statuscode': 100,
- 'message': null
- },
- 'data': {
- 'exact': {
- 'users': [],
- 'groups': [],
- 'remotes': []
- },
- 'users': [],
- 'groups': [
- {
- 'label': 'group',
- 'value': {
- 'shareType': OC.Share.SHARE_TYPE_GROUP,
- 'shareWith': 'group'
- }
- },
- {
- 'label': 'group2',
- 'value': {
- 'shareType': OC.Share.SHARE_TYPE_GROUP,
- 'shareWith': 'group2'
- }
- }
- ],
- 'remotes': []
- }
- }
- });
- fakeServer.requests[0].respond(
- 200,
- {'Content-Type': 'application/json'},
- jsonData
- );
- expect(response.calledWithExactly([{
- 'label': 'group2',
- 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group2'}
- }])).toEqual(true);
- expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
- });
-
- it('remotes', function () {
- dialog.render();
- var response = sinon.stub();
- dialog.autocompleteHandler({term: 'bob'}, response);
- var jsonData = JSON.stringify({
- 'ocs': {
- 'meta': {
- 'status': 'success',
- 'statuscode': 100,
- 'message': null
- },
- 'data': {
- 'exact': {
- 'users': [],
- 'groups': [],
- 'remotes': []
- },
- 'users': [],
- 'groups': [],
- 'remotes': [
- {
- 'label': 'foo@bar.com/baz',
- 'value': {
- 'shareType': OC.Share.SHARE_TYPE_REMOTE,
- 'shareWith': 'foo@bar.com/baz'
- }
- },
- {
- 'label': 'foo2@bar.com/baz',
- 'value': {
- 'shareType': OC.Share.SHARE_TYPE_REMOTE,
- 'shareWith': 'foo2@bar.com/baz'
- }
- }
- ]
- }
- }
- });
- fakeServer.requests[0].respond(
- 200,
- {'Content-Type': 'application/json'},
- jsonData
- );
- expect(response.calledWithExactly([{
- 'label': 'foo2@bar.com/baz',
- 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo2@bar.com/baz'}
- }])).toEqual(true);
- expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
- });
- });
- });
-
- it('gracefully handles successful ajax call with failure content', function () {
- dialog.render();
- var response = sinon.stub();
- dialog.autocompleteHandler({term: 'bob'}, response);
- var jsonData = JSON.stringify({
- 'ocs' : {
- 'meta' : {
- 'status': 'failure',
- 'statuscode': 400
- }
- }
- });
- fakeServer.requests[0].respond(
- 200,
- {'Content-Type': 'application/json'},
- jsonData
- );
- expect(response.calledWithExactly()).toEqual(true);
- });
-
- 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();
- });
-
- describe('renders the autocomplete elements', function() {
- it('renders a group element', function() {
- dialog.render();
- var el = dialog.autocompleteRenderItem(
- $("<ul></ul>"),
- {label: "1", value: { shareType: OC.Share.SHARE_TYPE_GROUP }}
- );
- expect(el.is('li')).toEqual(true);
- expect(el.hasClass('group')).toEqual(true);
- });
-
- it('renders a remote element', function() {
- dialog.render();
- var el = dialog.autocompleteRenderItem(
- $("<ul></ul>"),
- {label: "1", value: { shareType: OC.Share.SHARE_TYPE_REMOTE }}
- );
- expect(el.is('li')).toEqual(true);
- expect(el.hasClass('user')).toEqual(true);
- });
- });
-
- it('calls addShare after selection', function() {
- dialog.render();
-
- var shareWith = $('.shareWithField')[0];
- var $shareWith = $(shareWith);
- var addShareStub = sinon.stub(shareModel, 'addShare');
- var autocompleteOptions = autocompleteStub.getCall(0).args[0];
- autocompleteOptions.select(new $.Event('select', {target: shareWith}), {
- item: {
- label: 'User Two',
- value: {
- shareType: OC.Share.SHARE_TYPE_USER,
- shareWith: 'user2'
- }
- }
- });
-
- expect(addShareStub.calledOnce).toEqual(true);
- expect(addShareStub.firstCall.args[0]).toEqual({
- shareType: OC.Share.SHARE_TYPE_USER,
- shareWith: 'user2'
- });
-
- //Input is locked
- expect($shareWith.val()).toEqual('User Two');
- expect($shareWith.attr('disabled')).toEqual('disabled');
-
- //Callback is called
- addShareStub.firstCall.args[1].success();
-
- //Input is unlocked
- expect($shareWith.val()).toEqual('');
- expect($shareWith.attr('disabled')).toEqual(undefined);
-
- addShareStub.restore();
- });
-
- it('calls addShare after selection and fail to share', function() {
- dialog.render();
-
- var shareWith = $('.shareWithField')[0];
- var $shareWith = $(shareWith);
- var addShareStub = sinon.stub(shareModel, 'addShare');
- var autocompleteOptions = autocompleteStub.getCall(0).args[0];
- autocompleteOptions.select(new $.Event('select', {target: shareWith}), {
- item: {
- label: 'User Two',
- value: {
- shareType: OC.Share.SHARE_TYPE_USER,
- shareWith: 'user2'
- }
- }
- });
-
- expect(addShareStub.calledOnce).toEqual(true);
- expect(addShareStub.firstCall.args[0]).toEqual({
- shareType: OC.Share.SHARE_TYPE_USER,
- shareWith: 'user2'
- });
-
- //Input is locked
- expect($shareWith.val()).toEqual('User Two');
- expect($shareWith.attr('disabled')).toEqual('disabled');
-
- //Callback is called
- addShareStub.firstCall.args[1].error();
-
- //Input is unlocked
- expect($shareWith.val()).toEqual('User Two');
- expect($shareWith.attr('disabled')).toEqual(undefined);
-
- addShareStub.restore();
- });
- });
- describe('reshare permissions', function() {
- it('does not show sharing options when sharing not allowed', function() {
- shareModel.set({
- reshare: {},
- shares: [],
- permissions: OC.PERMISSION_READ
- });
- dialog.render();
- expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true);
- });
- it('shows reshare owner', function() {
- shareModel.set({
- reshare: {
- uid_owner: 'user1'
- },
- shares: [],
- permissions: OC.PERMISSION_READ
- });
- dialog.render();
- expect(dialog.$el.find('.resharerInfoView .reshare').length).toEqual(1);
- });
- it('does not show reshare owner if owner is current user', function() {
- shareModel.set({
- reshare: {
- uid_owner: OC.currentUser
- },
- shares: [],
- permissions: OC.PERMISSION_READ
- });
- dialog.render();
- expect(dialog.$el.find('.resharerInfoView .reshare').length).toEqual(0);
- });
- });
-});
diff --git a/core/js/tests/specs/shareitemmodelSpec.js b/core/js/tests/specs/shareitemmodelSpec.js
deleted file mode 100644
index 8c9560d2646..00000000000
--- a/core/js/tests/specs/shareitemmodelSpec.js
+++ /dev/null
@@ -1,828 +0,0 @@
-/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2015 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/>.
-*
-*/
-
-/* global oc_appconfig */
-describe('OC.Share.ShareItemModel', function() {
- var fetchSharesStub, fetchReshareStub;
- var fetchSharesDeferred, fetchReshareDeferred;
- var fileInfoModel, configModel, model;
- var oldCurrentUser;
-
- beforeEach(function() {
- oldCurrentUser = OC.currentUser;
-
- fetchSharesDeferred = new $.Deferred();
- fetchSharesStub = sinon.stub(OC.Share.ShareItemModel.prototype, '_fetchShares')
- .returns(fetchSharesDeferred.promise());
- fetchReshareDeferred = new $.Deferred();
- fetchReshareStub = sinon.stub(OC.Share.ShareItemModel.prototype, '_fetchReshare')
- .returns(fetchReshareDeferred.promise());
-
- 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: fileInfoModel.get('sharePermissions')
- };
- configModel = new OC.Share.ShareConfigModel();
- model = new OC.Share.ShareItemModel(attributes, {
- configModel: configModel,
- fileInfoModel: fileInfoModel
- });
- });
- afterEach(function() {
- if (fetchSharesStub) {
- fetchSharesStub.restore();
- }
- if (fetchReshareStub) {
- fetchReshareStub.restore();
- }
- OC.currentUser = oldCurrentUser;
- });
-
- function makeOcsResponse(data) {
- return [{
- ocs: {
- data: data
- }
- }];
- }
-
- describe('Fetching and parsing', function() {
- it('fetches both outgoing shares and the current incoming share', function() {
- model.fetch();
-
- expect(fetchSharesStub.calledOnce).toEqual(true);
- expect(fetchReshareStub.calledOnce).toEqual(true);
- });
- it('fetches shares for the current path', function() {
- fetchSharesStub.restore();
-
- model._fetchShares();
-
- expect(fakeServer.requests.length).toEqual(1);
- expect(fakeServer.requests[0].method).toEqual('GET');
- expect(fakeServer.requests[0].url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1', 2) +
- 'shares?format=json&path=%2Fsubdir%2Fshared_file_name.txt&reshares=true'
- );
-
- fetchSharesStub = null;
- });
- it('fetches reshare for the current path', function() {
- fetchReshareStub.restore();
-
- model._fetchReshare();
-
- expect(fakeServer.requests.length).toEqual(1);
- expect(fakeServer.requests[0].method).toEqual('GET');
- expect(fakeServer.requests[0].url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1', 2) +
- 'shares?format=json&path=%2Fsubdir%2Fshared_file_name.txt&shared_with_me=true'
- );
-
- fetchReshareStub = null;
- });
- it('populates attributes with parsed response', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([
- {
- share_type: OC.Share.SHARE_TYPE_USER,
- uid_owner: 'owner',
- displayname_owner: 'Owner',
- permissions: 31
- }
- ]));
- fetchSharesDeferred.resolve(makeOcsResponse([
- {
- id: 100,
- item_source: 123,
- permissions: 31,
- share_type: OC.Share.SHARE_TYPE_USER,
- share_with: 'user1',
- share_with_displayname: 'User One'
- }, {
- id: 101,
- item_source: 123,
- permissions: 31,
- share_type: OC.Share.SHARE_TYPE_GROUP,
- share_with: 'group',
- share_with_displayname: 'group'
- }, {
- id: 102,
- item_source: 123,
- permissions: 31,
- share_type: OC.Share.SHARE_TYPE_REMOTE,
- share_with: 'foo@bar.com/baz',
- share_with_displayname: 'foo@bar.com/baz'
-
- }, {
- displayname_owner: 'root',
- expiration: null,
- file_source: 123,
- file_target: '/folder',
- id: 20,
- item_source: '123',
- item_type: 'folder',
- mail_send: '0',
- parent: null,
- path: '/folder',
- permissions: OC.PERMISSION_READ,
- share_type: OC.Share.SHARE_TYPE_LINK,
- share_with: null,
- stime: 1403884258,
- storage: 1,
- token: 'tehtoken',
- uid_owner: 'root'
- }
- ]));
-
- OC.currentUser = 'root';
-
- model.fetch();
-
- var shares = model.get('shares');
- expect(shares.length).toEqual(3);
- expect(shares[0].id).toEqual(100);
- expect(shares[0].permissions).toEqual(31);
- expect(shares[0].share_type).toEqual(OC.Share.SHARE_TYPE_USER);
- expect(shares[0].share_with).toEqual('user1');
- expect(shares[0].share_with_displayname).toEqual('User One');
-
- var linkShare = model.get('linkShare');
- expect(linkShare.isLinkShare).toEqual(true);
-
- // TODO: check more attributes
- });
- it('does not parse link share when for a different file', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([]));
- fetchSharesDeferred.resolve(makeOcsResponse([{
- displayname_owner: 'root',
- expiration: null,
- file_source: 456,
- file_target: '/folder',
- id: 20,
- item_source: '456',
- item_type: 'folder',
- mail_send: '0',
- parent: null,
- path: '/folder',
- permissions: OC.PERMISSION_READ,
- share_type: OC.Share.SHARE_TYPE_LINK,
- share_with: null,
- stime: 1403884258,
- storage: 1,
- token: 'tehtoken',
- uid_owner: 'root'
- }]
- ));
-
- model.fetch();
-
- var shares = model.get('shares');
- // remaining share appears in this list
- expect(shares.length).toEqual(1);
-
- var linkShare = model.get('linkShare');
- expect(linkShare.isLinkShare).toEqual(false);
- });
- it('parses correct link share when a nested link share exists along with parent one', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([]));
- fetchSharesDeferred.resolve(makeOcsResponse([{
- displayname_owner: 'root',
- expiration: '2015-10-12 00:00:00',
- file_source: 123,
- file_target: '/folder',
- id: 20,
- item_source: '123',
- item_type: 'file',
- mail_send: '0',
- parent: null,
- path: '/folder',
- permissions: OC.PERMISSION_READ,
- share_type: OC.Share.SHARE_TYPE_LINK,
- share_with: null,
- stime: 1403884258,
- storage: 1,
- token: 'tehtoken',
- uid_owner: 'root'
- }, {
- displayname_owner: 'root',
- expiration: '2015-10-15 00:00:00',
- file_source: 456,
- file_target: '/file_in_folder.txt',
- id: 21,
- item_source: '456',
- item_type: 'file',
- mail_send: '0',
- parent: null,
- path: '/folder/file_in_folder.txt',
- permissions: OC.PERMISSION_READ,
- share_type: OC.Share.SHARE_TYPE_LINK,
- share_with: null,
- stime: 1403884509,
- storage: 1,
- token: 'anothertoken',
- uid_owner: 'root'
- }]
- ));
- OC.currentUser = 'root';
- model.fetch();
-
- var shares = model.get('shares');
- // the parent share remains in the list
- expect(shares.length).toEqual(1);
-
- var linkShare = model.get('linkShare');
- expect(linkShare.isLinkShare).toEqual(true);
- expect(linkShare.token).toEqual('tehtoken');
-
- // TODO: check child too
- });
- it('reduces reshare permissions to the ones from the original share', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([{
- id: 123,
- permissions: OC.PERMISSION_READ,
- uid_owner: 'user1'
- }]));
- fetchSharesDeferred.resolve(makeOcsResponse([]));
- model.fetch();
-
- // no resharing allowed
- expect(model.get('permissions')).toEqual(OC.PERMISSION_READ);
- });
- it('reduces reshare permissions to possible permissions', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([{
- id: 123,
- permissions: OC.PERMISSION_ALL,
- uid_owner: 'user1'
- }]));
- fetchSharesDeferred.resolve(makeOcsResponse([]));
-
- model.set('possiblePermissions', OC.PERMISSION_READ);
- model.fetch();
-
- // no resharing allowed
- expect(model.get('permissions')).toEqual(OC.PERMISSION_READ);
- });
- it('allows owner to share their own share when they are also the recipient', function() {
- OC.currentUser = 'user1';
- fetchReshareDeferred.resolve(makeOcsResponse([]));
- fetchSharesDeferred.resolve(makeOcsResponse([]));
-
- model.fetch();
-
- // sharing still allowed
- expect(model.get('permissions') & OC.PERMISSION_SHARE).toEqual(OC.PERMISSION_SHARE);
- });
- it('properly parses integer values when the server is in the mood of returning ints as string', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([]));
- fetchSharesDeferred.resolve(makeOcsResponse([{
- displayname_owner: 'root',
- expiration: '2015-10-12 00:00:00',
- file_source: '123',
- file_target: '/folder',
- id: '20',
- item_source: '123',
- item_type: 'file',
- mail_send: '0',
- parent: '999',
- path: '/folder',
- permissions: '' + OC.PERMISSION_READ,
- share_type: '' + OC.Share.SHARE_TYPE_USER,
- share_with: 'user1',
- stime: '1403884258',
- storage: '1',
- token: 'tehtoken',
- uid_owner: 'root'
- }]
- ));
-
- model.fetch();
-
- var shares = model.get('shares');
- expect(shares.length).toEqual(1);
-
- var share = shares[0];
- expect(share.id).toEqual(20);
- expect(share.file_source).toEqual(123);
- expect(share.file_target).toEqual('/folder');
- expect(share.item_source).toEqual(123);
- expect(share.item_type).toEqual('file');
- expect(share.displayname_owner).toEqual('root');
- expect(share.mail_send).toEqual(0);
- expect(share.parent).toEqual(999);
- expect(share.path).toEqual('/folder');
- expect(share.permissions).toEqual(OC.PERMISSION_READ);
- expect(share.share_type).toEqual(OC.Share.SHARE_TYPE_USER);
- expect(share.share_with).toEqual('user1');
- expect(share.stime).toEqual(1403884258);
- expect(share.expiration).toEqual('2015-10-12 00:00:00');
- });
- });
- describe('hasUserShares', function() {
- it('returns false when no user shares exist', function() {
- fetchReshareDeferred.resolve(makeOcsResponse([]));
- fetchSharesDeferred.resolve(makeOcsResponse([]));
-
- model.fetch();
-
- expect(model.hasUserShares()).toEqual(false);
- });
- it('returns true when user shares exist on the current item', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([]));
- fetchSharesDeferred.resolve(makeOcsResponse([{
- id: 1,
- share_type: OC.Share.SHARE_TYPE_USER,
- share_with: 'user1',
- item_source: '123'
- }]));
-
- model.fetch();
-
- expect(model.hasUserShares()).toEqual(true);
- });
- it('returns true when group shares exist on the current item', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([]));
- fetchSharesDeferred.resolve(makeOcsResponse([{
- id: 1,
- share_type: OC.Share.SHARE_TYPE_GROUP,
- share_with: 'group1',
- item_source: '123'
- }]));
-
- model.fetch();
-
- expect(model.hasUserShares()).toEqual(true);
- });
- it('returns false when share exist on parent item', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([]));
- fetchSharesDeferred.resolve(makeOcsResponse([{
- id: 1,
- share_type: OC.Share.SHARE_TYPE_GROUP,
- share_with: 'group1',
- item_source: '111'
- }]));
-
- model.fetch();
-
- expect(model.hasUserShares()).toEqual(false);
- });
- });
-
- describe('Util', function() {
- it('parseTime should properly parse strings', function() {
-
- _.each([
- [ '123456', 123456],
- [ 123456 , 123456],
- ['0123456', 123456],
- ['abcdefg', null],
- ['0x12345', null],
- [ '', null],
- ], function(value) {
- expect(OC.Share.ShareItemModel.prototype._parseTime(value[0])).toEqual(value[1]);
- });
-
- });
- });
-
- describe('sendEmailPrivateLink', function() {
- it('succeeds', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([]));
- fetchSharesDeferred.resolve(makeOcsResponse([{
- displayname_owner: 'root',
- expiration: null,
- file_source: 123,
- file_target: '/folder',
- id: 20,
- item_source: '123',
- item_type: 'folder',
- mail_send: '0',
- parent: null,
- path: '/folder',
- permissions: OC.PERMISSION_READ,
- share_type: OC.Share.SHARE_TYPE_LINK,
- share_with: null,
- stime: 1403884258,
- storage: 1,
- token: 'tehtoken',
- uid_owner: 'root'
- }]));
- OC.currentUser = 'root';
- model.fetch();
-
- var res = model.sendEmailPrivateLink('foo@bar.com');
-
- expect(res.state()).toEqual('pending');
- expect(fakeServer.requests.length).toEqual(1);
- expect(fakeServer.requests[0].url).toEqual(OC.generateUrl('core/ajax/share.php'));
- expect(OC.parseQueryString(fakeServer.requests[0].requestBody)).toEqual(
- {
- action: 'email',
- toaddress: 'foo@bar.com',
- link: model.get('linkShare').link,
- itemType: 'file',
- itemSource: '123',
- file: 'shared_file_name.txt',
- expiration: ''
- }
- )
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({status: 'success'})
- );
- expect(res.state()).toEqual('resolved');
- });
-
- it('fails', function() {
- /* jshint camelcase: false */
- fetchReshareDeferred.resolve(makeOcsResponse([]));
- fetchSharesDeferred.resolve(makeOcsResponse([{
- displayname_owner: 'root',
- expiration: null,
- file_source: 123,
- file_target: '/folder',
- id: 20,
- item_source: '123',
- item_type: 'folder',
- mail_send: '0',
- parent: null,
- path: '/folder',
- permissions: OC.PERMISSION_READ,
- share_type: OC.Share.SHARE_TYPE_LINK,
- share_with: null,
- stime: 1403884258,
- storage: 1,
- token: 'tehtoken',
- uid_owner: 'root'
- }]));
- OC.currentUser = 'root';
- model.fetch();
-
- var res = model.sendEmailPrivateLink('foo@bar.com');
-
- expect(res.state()).toEqual('pending');
- expect(fakeServer.requests.length).toEqual(1);
- expect(fakeServer.requests[0].url).toEqual(OC.generateUrl('core/ajax/share.php'));
- expect(OC.parseQueryString(fakeServer.requests[0].requestBody)).toEqual(
- {
- action: 'email',
- toaddress: 'foo@bar.com',
- link: model.get('linkShare').link,
- itemType: 'file',
- itemSource: '123',
- file: 'shared_file_name.txt',
- expiration: ''
- }
- )
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({data: {message: 'fail'}, status: 'error'})
- );
- expect(res.state()).toEqual('rejected');
- });
- });
- describe('share permissions', function() {
- beforeEach(function() {
- oc_appconfig.core.resharingAllowed = true;
- });
-
- /**
- * Tests sharing with the given possible permissions
- *
- * @param {int} possiblePermissions
- * @return {int} permissions sent to the server
- */
- function testWithPermissions(possiblePermissions) {
- model.set({
- permissions: possiblePermissions,
- possiblePermissions: possiblePermissions
- });
- model.addShare({
- shareType: OC.Share.SHARE_TYPE_USER,
- shareWith: 'user2'
- });
-
- var requestBody = OC.parseQueryString(_.last(fakeServer.requests).requestBody);
- return parseInt(requestBody.permissions, 10);
- }
-
- describe('regular sharing', function() {
- it('shares with given permissions with default config', function() {
- configModel.set('isResharingAllowed', true);
- model.set({
- reshare: {},
- shares: []
- });
- expect(
- testWithPermissions(OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE)
- ).toEqual(OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE);
- expect(
- testWithPermissions(OC.PERMISSION_READ | OC.PERMISSION_SHARE)
- ).toEqual(OC.PERMISSION_READ | OC.PERMISSION_SHARE);
- });
- it('removes share permission when not allowed', function() {
- configModel.set('isResharingAllowed', false);
- model.set({
- reshare: {},
- shares: []
- });
- expect(
- testWithPermissions(OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE)
- ).toEqual(OC.PERMISSION_READ | OC.PERMISSION_UPDATE);
- });
- it('automatically adds READ permission even when not specified', function() {
- configModel.set('isResharingAllowed', false);
- model.set({
- reshare: {},
- shares: []
- });
- expect(
- testWithPermissions(OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE)
- ).toEqual(OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_UPDATE);
- });
- });
- });
-
- describe('saveLinkShare', function() {
- var addShareStub;
- var updateShareStub;
-
- beforeEach(function() {
- addShareStub = sinon.stub(model, 'addShare');
- updateShareStub = sinon.stub(model, 'updateShare');
- });
- afterEach(function() {
- addShareStub.restore();
- updateShareStub.restore();
- });
-
- it('creates a new share if no link share exists', function() {
- model.set({
- linkShare: {
- isLinkShare: false
- }
- });
-
- model.saveLinkShare();
-
- expect(addShareStub.calledOnce).toEqual(true);
- expect(addShareStub.firstCall.args[0]).toEqual({
- password: '',
- passwordChanged: false,
- permissions: OC.PERMISSION_READ,
- expireDate: '',
- shareType: OC.Share.SHARE_TYPE_LINK
- });
- expect(updateShareStub.notCalled).toEqual(true);
- });
- it('creates a new share with default expiration date', function() {
- var clock = sinon.useFakeTimers(Date.UTC(2015, 6, 17, 1, 2, 0, 3));
- configModel.set({
- isDefaultExpireDateEnabled: true,
- defaultExpireDate: 7
- });
- model.set({
- linkShare: {
- isLinkShare: false
- }
- });
-
- model.saveLinkShare();
-
- expect(addShareStub.calledOnce).toEqual(true);
- expect(addShareStub.firstCall.args[0]).toEqual({
- password: '',
- passwordChanged: false,
- permissions: OC.PERMISSION_READ,
- expireDate: '2015-07-24 00:00:00',
- shareType: OC.Share.SHARE_TYPE_LINK
- });
- expect(updateShareStub.notCalled).toEqual(true);
- clock.restore();
- });
- it('updates link share if it exists', function() {
- model.set({
- linkShare: {
- isLinkShare: true,
- id: 123
- }
- });
-
- model.saveLinkShare({
- password: 'test'
- });
-
- expect(addShareStub.notCalled).toEqual(true);
- expect(updateShareStub.calledOnce).toEqual(true);
- expect(updateShareStub.firstCall.args[0]).toEqual(123);
- expect(updateShareStub.firstCall.args[1]).toEqual({
- password: 'test'
- });
- });
- it('forwards error message on add', function() {
- var errorStub = sinon.stub();
- model.set({
- linkShare: {
- isLinkShare: false
- }
- }, {
- });
-
- model.saveLinkShare({
- password: 'test'
- }, {
- error: errorStub
- });
-
- addShareStub.yieldTo('error', 'Some error message');
-
- expect(errorStub.calledOnce).toEqual(true);
- expect(errorStub.lastCall.args[0]).toEqual('Some error message');
- });
- it('forwards error message on update', function() {
- var errorStub = sinon.stub();
- model.set({
- linkShare: {
- isLinkShare: true,
- id: '123'
- }
- }, {
- });
-
- model.saveLinkShare({
- password: 'test'
- }, {
- error: errorStub
- });
-
- updateShareStub.yieldTo('error', 'Some error message');
-
- expect(errorStub.calledOnce).toEqual(true);
- expect(errorStub.lastCall.args[0]).toEqual('Some error message');
- });
- });
- describe('creating shares', function() {
- it('sends POST method to endpoint with passed values', function() {
- model.addShare({
- shareType: OC.Share.SHARE_TYPE_GROUP,
- shareWith: 'group1'
- });
-
- expect(fakeServer.requests.length).toEqual(1);
- expect(fakeServer.requests[0].method).toEqual('POST');
- expect(fakeServer.requests[0].url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1', 2) +
- 'shares?format=json'
- );
- expect(OC.parseQueryString(fakeServer.requests[0].requestBody)).toEqual({
- path: '/subdir/shared_file_name.txt',
- permissions: '' + OC.PERMISSION_READ,
- shareType: '' + OC.Share.SHARE_TYPE_GROUP,
- shareWith: 'group1'
- });
- });
- it('calls error handler with error message', function() {
- var errorStub = sinon.stub();
- model.addShare({
- shareType: OC.Share.SHARE_TYPE_GROUP,
- shareWith: 'group1'
- }, {
- error: errorStub
- });
-
- expect(fakeServer.requests.length).toEqual(1);
- fakeServer.requests[0].respond(
- 400,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- ocs: {
- meta: {
- message: 'Some error message'
- }
- }
- })
- );
-
- expect(errorStub.calledOnce).toEqual(true);
- expect(errorStub.lastCall.args[1]).toEqual('Some error message');
- });
- });
- describe('updating shares', function() {
- it('sends PUT method to endpoint with passed values', function() {
- model.updateShare(123, {
- permissions: OC.PERMISSION_READ | OC.PERMISSION_SHARE
- });
-
- expect(fakeServer.requests.length).toEqual(1);
- expect(fakeServer.requests[0].method).toEqual('PUT');
- expect(fakeServer.requests[0].url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1', 2) +
- 'shares/123?format=json'
- );
- expect(OC.parseQueryString(fakeServer.requests[0].requestBody)).toEqual({
- permissions: '' + (OC.PERMISSION_READ | OC.PERMISSION_SHARE)
- });
- });
- it('calls error handler with error message', function() {
- var errorStub = sinon.stub();
- model.updateShare(123, {
- permissions: OC.PERMISSION_READ | OC.PERMISSION_SHARE
- }, {
- error: errorStub
- });
-
- expect(fakeServer.requests.length).toEqual(1);
- fakeServer.requests[0].respond(
- 400,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- ocs: {
- meta: {
- message: 'Some error message'
- }
- }
- })
- );
-
- expect(errorStub.calledOnce).toEqual(true);
- expect(errorStub.lastCall.args[1]).toEqual('Some error message');
- });
- });
- describe('removing shares', function() {
- it('sends DELETE method to endpoint with share id', function() {
- model.removeShare(123);
-
- expect(fakeServer.requests.length).toEqual(1);
- expect(fakeServer.requests[0].method).toEqual('DELETE');
- expect(fakeServer.requests[0].url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1', 2) +
- 'shares/123?format=json'
- );
- });
- it('calls error handler with error message', function() {
- var errorStub = sinon.stub();
- model.removeShare(123, {
- error: errorStub
- });
-
- expect(fakeServer.requests.length).toEqual(1);
- fakeServer.requests[0].respond(
- 400,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- ocs: {
- meta: {
- message: 'Some error message'
- }
- }
- })
- );
-
- expect(errorStub.calledOnce).toEqual(true);
- expect(errorStub.lastCall.args[1]).toEqual('Some error message');
- });
- });
-});
-
diff --git a/core/js/tests/specs/systemtags/systemtagsSpec.js b/core/js/tests/specs/systemtags/systemtagsSpec.js
index 515b75258a0..52fe954f454 100644
--- a/core/js/tests/specs/systemtags/systemtagsSpec.js
+++ b/core/js/tests/specs/systemtags/systemtagsSpec.js
@@ -1,29 +1,14 @@
/**
-* ownCloud
-*
-* @author Joas Schilling
-* @copyright 2016 Joas Schilling <nickvergessen@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/>.
-*
-*/
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
describe('OC.SystemTags tests', function() {
it('describes non existing tag', function() {
var $return = OC.SystemTags.getDescriptiveTag('23');
- expect($return.text()).toEqual('Non-existing tag #23');
- expect($return.hasClass('non-existing-tag')).toEqual(true);
+ expect($return.textContent).toEqual('Non-existing tag #23');
+ expect($return.classList.contains('non-existing-tag')).toEqual(true);
});
it('describes SystemTagModel', function() {
@@ -34,8 +19,8 @@ describe('OC.SystemTags tests', function() {
userVisible: true
});
var $return = OC.SystemTags.getDescriptiveTag(tag);
- expect($return.text()).toEqual('Twenty Three');
- expect($return.hasClass('non-existing-tag')).toEqual(false);
+ expect($return.textContent).toEqual('Twenty Three');
+ expect($return.classList.contains('non-existing-tag')).toEqual(false);
});
it('describes JSON tag object', function() {
@@ -45,8 +30,8 @@ describe('OC.SystemTags tests', function() {
userAssignable: true,
userVisible: true
});
- expect($return.text()).toEqual('Fourty Two');
- expect($return.hasClass('non-existing-tag')).toEqual(false);
+ expect($return.textContent).toEqual('Fourty Two');
+ expect($return.classList.contains('non-existing-tag')).toEqual(false);
});
it('scope', function() {
@@ -57,13 +42,13 @@ describe('OC.SystemTags tests', function() {
userAssignable: userAssignable,
userVisible: userVisible
});
- expect($return.text()).toEqual(expectedText);
- expect($return.hasClass('non-existing-tag')).toEqual(false);
+ expect($return.textContent).toEqual(expectedText);
+ expect($return.classList.contains('non-existing-tag')).toEqual(false);
}
testScope(true, true, 'Fourty Two');
- testScope(false, true, 'Fourty Two (invisible)');
- testScope(false, false, 'Fourty Two (invisible)');
- testScope(true, false, 'Fourty Two (not assignable)');
+ testScope(false, true, 'Fourty Two (Invisible)');
+ testScope(false, false, 'Fourty Two (Invisible)');
+ testScope(true, false, 'Fourty Two (Restricted)');
});
});
diff --git a/core/js/tests/specs/systemtags/systemtagscollectionSpec.js b/core/js/tests/specs/systemtags/systemtagscollectionSpec.js
index 6f2d8361754..f2a3bd067a5 100644
--- a/core/js/tests/specs/systemtags/systemtagscollectionSpec.js
+++ b/core/js/tests/specs/systemtags/systemtagscollectionSpec.js
@@ -1,23 +1,7 @@
/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2016 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/>.
-*
-*/
+ * SPDX-FileCopyrightText: 2016 ownCloud Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
describe('OC.SystemTags.SystemTagsCollection tests', function() {
var collection;
diff --git a/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js b/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js
index 22bf0d2c82a..988bcfc8c24 100644
--- a/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js
+++ b/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js
@@ -1,23 +1,8 @@
/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2016 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/>.
-*
-*/
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
describe('OC.SystemTags.SystemTagsInputField tests', function() {
var view, select2Stub, clock;
@@ -68,7 +53,7 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
view.collection.add([
new OC.SystemTags.SystemTagModel({id: '1', name: 'abc'}),
new OC.SystemTags.SystemTagModel({id: '2', name: 'def'}),
- new OC.SystemTags.SystemTagModel({id: '3', name: 'abd', userAssignable: false}),
+ new OC.SystemTags.SystemTagModel({id: '3', name: 'abd', userAssignable: false, canAssign: false}),
]);
});
it('does not create dummy tag when user types non-matching name', function() {
@@ -84,6 +69,7 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
expect(result.isNew).toEqual(true);
expect(result.userVisible).toEqual(true);
expect(result.userAssignable).toEqual(true);
+ expect(result.canAssign).toEqual(true);
});
it('creates dummy tag when user types non-matching name even with prefix of existing tag', function() {
var opts = select2Stub.getCall(0).args[0];
@@ -93,6 +79,7 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
expect(result.isNew).toEqual(true);
expect(result.userVisible).toEqual(true);
expect(result.userAssignable).toEqual(true);
+ expect(result.canAssign).toEqual(true);
});
it('creates the real tag and fires select event after user selects the dummy tag', function() {
var selectHandler = sinon.stub();
@@ -110,14 +97,16 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
expect(createStub.getCall(0).args[0]).toEqual({
name: 'newname',
userVisible: true,
- userAssignable: true
+ userAssignable: true,
+ canAssign: true
});
var newModel = new OC.SystemTags.SystemTagModel({
id: '123',
name: 'newname',
userVisible: true,
- userAssignable: true
+ userAssignable: true,
+ canAssign: true
});
// not called yet
@@ -186,7 +175,8 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
expect(createStub.getCall(0).args[0]).toEqual({
name: 'newname',
userVisible: true,
- userAssignable: true
+ userAssignable: true,
+ canAssign: true
});
var newModel = new OC.SystemTags.SystemTagModel({
@@ -262,20 +252,6 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
saveStub.restore();
});
- it('deletes model and submits change when clicking delete', function() {
- var destroyStub = sinon.stub(OC.SystemTags.SystemTagModel.prototype, 'destroy');
-
- expect($dropdown.find('.delete').length).toEqual(0);
- $dropdown.find('.rename').mouseup();
- // delete button appears
- expect($dropdown.find('.delete').length).toEqual(1);
- $dropdown.find('.delete').mouseup();
-
- expect(destroyStub.calledOnce).toEqual(true);
- expect(destroyStub.calledOn(view.collection.get('1')));
-
- destroyStub.restore();
- });
});
describe('setting data', function() {
it('sets value when calling setValues', function() {
@@ -294,22 +270,28 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
});
describe('as admin', function() {
+ var $dropdown;
+
beforeEach(function() {
view = new OC.SystemTags.SystemTagsInputField({
isAdmin: true
});
- view.render();
$('.testInputContainer').append(view.$el);
+ $dropdown = $('<div class="select2-dropdown"></div>');
+ select2Stub.withArgs('dropdown').returns($dropdown);
+ $('#testArea').append($dropdown);
+
+ view.render();
});
it('formatResult renders tag name with visibility', function() {
var opts = select2Stub.getCall(0).args[0];
var $el = $(opts.formatResult({id: '1', name: 'test', userVisible: false, userAssignable: false}));
- expect($el.find('.label').text()).toEqual('test (invisible)');
+ expect($el.find('.label').text()).toEqual('test (Invisible)');
});
it('formatSelection renders tag name with visibility', function() {
var opts = select2Stub.getCall(0).args[0];
var $el = $(opts.formatSelection({id: '1', name: 'test', userVisible: false, userAssignable: false}));
- expect($el.text().trim()).toEqual('test (invisible)');
+ expect($el.text().trim()).toEqual('test (Invisible)');
});
describe('initSelection', function() {
var fetchStub;
@@ -320,7 +302,8 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
testTags = [
new OC.SystemTags.SystemTagModel({id: '1', name: 'test1'}),
new OC.SystemTags.SystemTagModel({id: '2', name: 'test2'}),
- new OC.SystemTags.SystemTagModel({id: '3', name: 'test3', userAssignable: false}),
+ new OC.SystemTags.SystemTagModel({id: '3', name: 'test3', userAssignable: false, canAssign: false}),
+ new OC.SystemTags.SystemTagModel({id: '4', name: 'test4', userAssignable: false, canAssign: true})
];
});
afterEach(function() {
@@ -328,7 +311,7 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
});
it('grabs values from the full collection', function() {
var $el = view.$el.find('input');
- $el.val('1,3');
+ $el.val('1,3,4');
var opts = select2Stub.getCall(0).args[0];
var callback = sinon.stub();
opts.initSelection($el, callback);
@@ -339,11 +322,16 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
expect(callback.calledOnce).toEqual(true);
var models = callback.getCall(0).args[0];
- expect(models.length).toEqual(2);
+ expect(models.length).toEqual(3);
expect(models[0].id).toEqual('1');
expect(models[0].name).toEqual('test1');
+ expect(models[0].locked).toBeFalsy();
expect(models[1].id).toEqual('3');
expect(models[1].name).toEqual('test3');
+ expect(models[1].locked).toBeFalsy();
+ expect(models[2].id).toEqual('4');
+ expect(models[2].name).toEqual('test4');
+ expect(models[2].locked).toBeFalsy();
});
});
describe('autocomplete', function() {
@@ -356,7 +344,7 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
view.collection.add([
new OC.SystemTags.SystemTagModel({id: '1', name: 'abc'}),
new OC.SystemTags.SystemTagModel({id: '2', name: 'def'}),
- new OC.SystemTags.SystemTagModel({id: '3', name: 'abd', userAssignable: false}),
+ new OC.SystemTags.SystemTagModel({id: '3', name: 'abd', userAssignable: false, canAssign: false}),
new OC.SystemTags.SystemTagModel({id: '4', name: 'Deg'}),
]);
});
@@ -379,13 +367,15 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
id: '1',
name: 'abc',
userVisible: true,
- userAssignable: true
+ userAssignable: true,
+ canAssign: true
},
{
id: '3',
name: 'abd',
userVisible: true,
- userAssignable: false
+ userAssignable: false,
+ canAssign: false
}
]);
});
@@ -405,26 +395,63 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
id: '2',
name: 'def',
userVisible: true,
- userAssignable: true
+ userAssignable: true,
+ canAssign: true
},
{
id: '4',
name: 'Deg',
userVisible: true,
- userAssignable: true
+ userAssignable: true,
+ canAssign: true
}
]);
});
});
+ describe('tag actions', function() {
+ var opts;
+
+ beforeEach(function() {
+
+ opts = select2Stub.getCall(0).args[0];
+
+ view.collection.add([
+ new OC.SystemTags.SystemTagModel({id: '1', name: 'abc'}),
+ ]);
+
+ $dropdown.append(opts.formatResult(view.collection.get('1').toJSON()));
+
+ });
+ it('deletes model and submits change when clicking delete', function() {
+ var destroyStub = sinon.stub(OC.SystemTags.SystemTagModel.prototype, 'destroy');
+
+ expect($dropdown.find('.delete').length).toEqual(0);
+ $dropdown.find('.rename').mouseup();
+ // delete button appears
+ expect($dropdown.find('.delete').length).toEqual(1);
+ $dropdown.find('.delete').mouseup();
+
+ expect(destroyStub.calledOnce).toEqual(true);
+ expect(destroyStub.calledOn(view.collection.get('1')));
+
+ destroyStub.restore();
+ });
+ });
});
describe('as user', function() {
+ var $dropdown;
+
beforeEach(function() {
view = new OC.SystemTags.SystemTagsInputField({
isAdmin: false
});
- view.render();
$('.testInputContainer').append(view.$el);
+ $dropdown = $('<div class="select2-dropdown"></div>');
+ select2Stub.withArgs('dropdown').returns($dropdown);
+ $('#testArea').append($dropdown);
+
+ view.render();
});
it('formatResult renders tag name only', function() {
var opts = select2Stub.getCall(0).args[0];
@@ -445,7 +472,8 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
testTags = [
new OC.SystemTags.SystemTagModel({id: '1', name: 'test1'}),
new OC.SystemTags.SystemTagModel({id: '2', name: 'test2'}),
- new OC.SystemTags.SystemTagModel({id: '3', name: 'test3', userAssignable: false}),
+ new OC.SystemTags.SystemTagModel({id: '3', name: 'test3', userAssignable: false, canAssign: false}),
+ new OC.SystemTags.SystemTagModel({id: '4', name: 'test4', userAssignable: false, canAssign: true})
];
view.render();
});
@@ -454,7 +482,7 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
});
it('grabs values from the full collection', function() {
var $el = view.$el.find('input');
- $el.val('1,3');
+ $el.val('1,3,4');
var opts = select2Stub.getCall(0).args[0];
var callback = sinon.stub();
opts.initSelection($el, callback);
@@ -465,11 +493,17 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
expect(callback.calledOnce).toEqual(true);
var models = callback.getCall(0).args[0];
- expect(models.length).toEqual(2);
+ expect(models.length).toEqual(3);
expect(models[0].id).toEqual('1');
expect(models[0].name).toEqual('test1');
+ expect(models[0].locked).toBeFalsy();
expect(models[1].id).toEqual('3');
expect(models[1].name).toEqual('test3');
+ // restricted / cannot assign locks the entry
+ expect(models[1].locked).toEqual(true);
+ expect(models[2].id).toEqual('4');
+ expect(models[2].name).toEqual('test4');
+ expect(models[2].locked).toBeFalsy();
});
});
describe('autocomplete', function() {
@@ -483,8 +517,9 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
view.collection.add([
new OC.SystemTags.SystemTagModel({id: '1', name: 'abc'}),
new OC.SystemTags.SystemTagModel({id: '2', name: 'def'}),
- new OC.SystemTags.SystemTagModel({id: '3', name: 'abd', userAssignable: false}),
+ new OC.SystemTags.SystemTagModel({id: '3', name: 'abd', userAssignable: false, canAssign: false}),
new OC.SystemTags.SystemTagModel({id: '4', name: 'Deg'}),
+ new OC.SystemTags.SystemTagModel({id: '5', name: 'abe', userAssignable: false, canAssign: true})
]);
});
afterEach(function() {
@@ -506,7 +541,15 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
id: '1',
name: 'abc',
userVisible: true,
- userAssignable: true
+ userAssignable: true,
+ canAssign: true
+ },
+ {
+ id: '5',
+ name: 'abe',
+ userVisible: true,
+ userAssignable: false,
+ canAssign: true
}
]);
});
@@ -526,16 +569,46 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() {
id: '2',
name: 'def',
userVisible: true,
- userAssignable: true
+ userAssignable: true,
+ canAssign: true
},
{
id: '4',
name: 'Deg',
userVisible: true,
- userAssignable: true
+ userAssignable: true,
+ canAssign: true
}
]);
});
});
+ describe('tag actions', function() {
+ var opts;
+
+ beforeEach(function() {
+
+ opts = select2Stub.getCall(0).args[0];
+
+ view.collection.add([
+ new OC.SystemTags.SystemTagModel({id: '1', name: 'abc'}),
+ ]);
+
+ $dropdown.append(opts.formatResult(view.collection.get('1').toJSON()));
+
+ });
+ it('deletes model and submits change when clicking delete', function() {
+ var destroyStub = sinon.stub(OC.SystemTags.SystemTagModel.prototype, 'destroy');
+
+ expect($dropdown.find('.delete').length).toEqual(0);
+ $dropdown.find('.rename').mouseup();
+ // delete button appears only for admins
+ expect($dropdown.find('.delete').length).toEqual(0);
+ $dropdown.find('.delete').mouseup();
+
+ expect(destroyStub.notCalled).toEqual(true);
+
+ destroyStub.restore();
+ });
+ });
});
});