migrate therinaldos.com data
Build & Deploy to DigitalOcean Space / build (push) Failing after 2m38s

This commit is contained in:
2024-05-05 15:50:45 -04:00
commit ef1ff240d4
23182 changed files with 3801898 additions and 0 deletions
@@ -0,0 +1,46 @@
/*
* DOMParser HTML extension
* 2012-09-04
*
* By Eli Grey, http://eligrey.com
* Public domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
/*! @source https://gist.github.com/1129031 */
/*global document, DOMParser*/
(function(DOMParser) {
"use strict";
var
DOMParser_proto = DOMParser.prototype
, real_parseFromString = DOMParser_proto.parseFromString
;
// Firefox/Opera/IE throw errors on unsupported types
try {
// WebKit returns null on unsupported types
if ((new DOMParser).parseFromString("", "text/html")) {
// text/html parsing is natively supported
return;
}
} catch (ex) {}
DOMParser_proto.parseFromString = function(markup, type) {
if (/^\s*text\/html\s*(?:;|$)/i.test(type)) {
var
doc = document.implementation.createHTMLDocument("")
;
if (markup.toLowerCase().indexOf('<!doctype') > -1) {
doc.documentElement.innerHTML = markup;
}
else {
doc.body.innerHTML = markup;
}
return doc;
} else {
return real_parseFromString.apply(this, arguments);
}
};
}(DOMParser));
+200
View File
@@ -0,0 +1,200 @@
/**
* 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/>.
*
*/
/**
* Simulate the variables that are normally set by PHP code
*/
// from core/js/config.php
window.TESTING = true;
window.datepickerFormatDate = 'MM d, yy';
window.dayNames = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
window.dayNamesShort = [
'Sun.',
'Mon.',
'Tue.',
'Wed.',
'Thu.',
'Fri.',
'Sat.'
];
window.dayNamesMin = [
'Su',
'Mo',
'Tu',
'We',
'Th',
'Fr',
'Sa'
];
window.monthNames = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
window.monthNamesShort = [
'Jan.',
'Feb.',
'Mar.',
'Apr.',
'May.',
'Jun.',
'Jul.',
'Aug.',
'Sep.',
'Oct.',
'Nov.',
'Dec.'
];
window.firstDay = 0;
// setup dummy webroots
/* jshint camelcase: false */
window.oc_debug = true;
// Mock @nextcloud/capabilities
window._oc_capabilities = {
files_sharing: {
api_enabled: true
}
}
// FIXME: OC.webroot is supposed to be only the path!!!
window._oc_webroot = location.href + '/';
window._oc_appswebroots = {
"files": window.webroot + '/apps/files/',
"files_sharing": window.webroot + '/apps/files_sharing/'
};
OC.config = {
session_lifetime: 600 * 1000,
session_keepalive: false,
blacklist_files_regex: '\.(part|filepart)$',
};
OC.appConfig = {
core: {}
};
OC.theme = {
docPlaceholderUrl: 'https://docs.example.org/PLACEHOLDER'
};
window.oc_capabilities = {
}
/* jshint camelcase: true */
// mock for Snap.js plugin
window.Snap = function() {};
window.Snap.prototype = {
enable: function() {},
disable: function() {},
close: function() {}
};
window.isPhantom = /phantom/i.test(navigator.userAgent);
document.documentElement.lang = navigator.language;
// global setup for all tests
(function setupTests() {
var fakeServer = null,
$testArea = null,
ajaxErrorStub = null;
/**
* Utility functions for testing
*/
var TestUtil = {
/**
* Returns the image URL set on the given element
* @param $el element
* @return {String} image URL
*/
getImageUrl: function($el) {
// might be slightly different cross-browser
var url = $el.css('background-image');
var r = url.match(/url\(['"]?([^'")]*)['"]?\)/);
if (!r) {
return url;
}
return r[1];
}
};
beforeEach(function() {
// test area for elements that need absolute selector access or measure widths/heights
// which wouldn't work for detached or hidden elements
$testArea = $('<div id="testArea" style="position: absolute; width: 1280px; height: 800px; top: -3000px; left: -3000px; opacity: 0;"></div>');
$('body').append($testArea);
// enforce fake XHR, tests should not depend on the server and
// must use fake responses for expected calls
fakeServer = sinon.fakeServer.create();
// make it globally available, so that other tests can define
// custom responses
window.fakeServer = fakeServer;
if (!OC.TestUtil) {
OC.TestUtil = TestUtil;
}
moment.locale('en');
// reset plugins
OC.Plugins._plugins = [];
// dummy select2 (which isn't loaded during the tests)
$.fn.select2 = function() { return this; };
ajaxErrorStub = sinon.stub(OC, '_processAjaxError');
});
afterEach(function() {
// uncomment this to log requests
// console.log(window.fakeServer.requests);
fakeServer.restore();
$testArea.remove();
delete($.fn.select2);
ajaxErrorStub.restore();
// reset pop state handlers
OC.Util.History._handlers = [];
});
})();
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,866 @@
/**
* 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 dav */
describe('OC.Files.Client tests', function() {
var Client = OC.Files.Client;
var baseUrl;
var client;
var requestStub;
var requestDeferred;
beforeEach(function() {
requestDeferred = new $.Deferred();
requestStub = sinon.stub(dav.Client.prototype, 'request').returns(requestDeferred.promise());
baseUrl = 'https://testhost/owncloud/remote.php/webdav/';
client = new Client({
host: 'testhost',
root: '/owncloud/remote.php/webdav',
useHTTPS: true
});
});
afterEach(function() {
client = null;
requestStub.restore();
});
/**
* Send an status response and check that the given
* promise gets its success handler called with the error
* status code
*
* @param {Promise} promise promise
* @param {number} status status to test
*/
function respondAndCheckStatus(promise, status) {
var successHandler = sinon.stub();
var failHandler = sinon.stub();
promise.done(successHandler);
promise.fail(failHandler);
requestDeferred.resolve({
status: status,
body: ''
});
promise.then(function() {
expect(successHandler.calledOnce).toEqual(true);
expect(successHandler.getCall(0).args[0]).toEqual(status);
expect(failHandler.notCalled).toEqual(true);
});
return promise;
}
/**
* Send an error response and check that the given
* promise gets its fail handler called with the error
* status code
*
* @param {Promise} promise promise object
* @param {number} status error status to test
*/
function respondAndCheckError(promise, status) {
var successHandler = sinon.stub();
var failHandler = sinon.stub();
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: errorXml,
xhr: {
responseXML: parser.parseFromString(errorXml, 'application/xml')
}
});
promise.then(function() {
expect(failHandler.calledOnce).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);
});
return promise;
}
/**
* Returns a list of request properties parsed from the given request body.
*
* @param {string} requestBody request XML
*
* @return {Array.<String>} array of request properties in the format
* "{NS:}propname"
*/
function getRequestedProperties(requestBody) {
var doc = (new window.DOMParser()).parseFromString(
requestBody,
'application/xml'
);
var propRoots = doc.getElementsByTagNameNS('DAV:', 'prop');
var propsList = propRoots.item(0).childNodes;
return _.map(propsList, function(propNode) {
return '{' + propNode.namespaceURI + '}' + propNode.localName;
});
}
function makePropBlock(props) {
var s = '<d:prop>\n';
_.each(props, function(value, key) {
s += '<' + key + '>' + value + '</' + key + '>\n';
});
return s + '</d:prop>\n';
}
function makeResponseBlock(href, props, failedProps) {
var s = '<d:response>\n';
s += '<d:href>' + href + '</d:href>\n';
s += '<d:propstat>\n';
s += makePropBlock(props);
s += '<d:status>HTTP/1.1 200 OK</d:status>';
s += '</d:propstat>\n';
if (failedProps) {
s += '<d:propstat>\n';
_.each(failedProps, function(prop) {
s += '<' + prop + '/>\n';
});
s += '<d:status>HTTP/1.1 404 Not Found</d:status>\n';
s += '</d:propstat>\n';
}
return s + '</d:response>\n';
}
describe('file listing', function() {
// TODO: switch this to the already parsed structure
var folderContentsXml = 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">' +
makeResponseBlock(
'/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/',
{
'd:getlastmodified': 'Fri, 10 Jul 2015 10:00:05 GMT',
'd:getetag': '"56cfcabd79abb"',
'd:resourcetype': '<d:collection/>',
'oc:id': '00000011oc2d13a6a068',
'oc:fileid': '11',
'oc:permissions': 'GRDNVCK',
'oc:size': '120'
},
[
'd:getcontenttype',
'd:getcontentlength'
]
) +
makeResponseBlock(
'/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/One.txt',
{
'd:getlastmodified': 'Fri, 10 Jul 2015 13:38:05 GMT',
'd:getetag': '"559fcabd79a38"',
'd:getcontenttype': 'text/plain',
'd:getcontentlength': 250,
'd:resourcetype': '',
'oc:id': '00000051oc2d13a6a068',
'oc:fileid': '51',
'oc:permissions': 'RDNVW'
},
[
'oc:size',
]
) +
makeResponseBlock(
'/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/sub',
{
'd:getlastmodified': 'Fri, 10 Jul 2015 14:00:00 GMT',
'd:getetag': '"66cfcabd79abb"',
'd:resourcetype': '<d:collection/>',
'oc:id': '00000015oc2d13a6a068',
'oc:fileid': '15',
'oc:permissions': 'GRDNVCK',
'oc:size': '100'
},
[
'd:getcontenttype',
'd:getcontentlength'
]
) +
'</d:multistatus>'
);
it('sends PROPFIND with explicit properties to get file list', function() {
client.getFolderContents('path/to space/文件夹');
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');
var props = getRequestedProperties(requestStub.lastCall.args[3]);
expect(props).toContain('{DAV:}getlastmodified');
expect(props).toContain('{DAV:}getcontentlength');
expect(props).toContain('{DAV:}getcontenttype');
expect(props).toContain('{DAV:}getetag');
expect(props).toContain('{DAV:}resourcetype');
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('');
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[1]).toEqual(baseUrl);
});
it('sends PROPFIND to base url when root path given', function() {
client.getFolderContents('/');
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[1]).toEqual(baseUrl);
});
it('parses the result list into a FileInfo array', function() {
var promise = client.getFolderContents('path/to space/文件夹');
expect(requestStub.calledOnce).toEqual(true);
requestDeferred.resolve({
status: 207,
body: folderContentsXml
});
promise.then(function(status, response) {
expect(status).toEqual(207);
expect(_.isArray(response)).toEqual(true);
expect(response.length).toEqual(2);
// file entry
var info = response[0];
expect(info instanceof OC.Files.FileInfo).toEqual(true);
expect(info.id).toEqual(51);
expect(info.path).toEqual('/path/to space/文件夹');
expect(info.name).toEqual('One.txt');
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];
expect(info instanceof OC.Files.FileInfo).toEqual(true);
expect(info.id).toEqual(15);
expect(info.path).toEqual('/path/to space/文件夹');
expect(info.name).toEqual('sub');
expect(info.permissions).toEqual(31);
expect(info.size).toEqual(100);
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() {
var promise = client.getFolderContents('path/to space/文件夹', {includeParent: true});
expect(requestStub.calledOnce).toEqual(true);
requestDeferred.resolve({
status: 207,
body: folderContentsXml
});
promise.then(function(status, response) {
expect(status).toEqual(207);
expect(_.isArray(response)).toEqual(true);
expect(response.length).toEqual(3);
// root entry
var info = response[0];
expect(info instanceof OC.Files.FileInfo).toEqual(true);
expect(info.id).toEqual(11);
expect(info.path).toEqual('/path/to space');
expect(info.name).toEqual('文件夹');
expect(info.permissions).toEqual(31);
expect(info.size).toEqual(120);
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);
expect(response[2].id).toEqual(15);
});
});
it('rejects promise when an error occurred', function() {
var promise = client.getFolderContents('path/to space/文件夹', {includeParent: true});
respondAndCheckError(promise, 404);
});
it('throws exception if arguments are missing', function() {
// TODO
});
});
describe('file filtering', function() {
// TODO: switch this to the already parsed structure
var folderContentsXml = 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">' +
makeResponseBlock(
'/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/',
{
'd:getlastmodified': 'Fri, 10 Jul 2015 10:00:05 GMT',
'd:getetag': '"56cfcabd79abb"',
'd:resourcetype': '<d:collection/>',
'oc:id': '00000011oc2d13a6a068',
'oc:fileid': '11',
'oc:permissions': 'RDNVCK',
'oc:size': '120'
},
[
'd:getcontenttype',
'd:getcontentlength'
]
) +
makeResponseBlock(
'/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/One.txt',
{
'd:getlastmodified': 'Fri, 10 Jul 2015 13:38:05 GMT',
'd:getetag': '"559fcabd79a38"',
'd:getcontenttype': 'text/plain',
'd:getcontentlength': 250,
'd:resourcetype': '',
'oc:id': '00000051oc2d13a6a068',
'oc:fileid': '51',
'oc:permissions': 'RDNVW'
},
[
'oc:size',
]
) +
makeResponseBlock(
'/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/sub',
{
'd:getlastmodified': 'Fri, 10 Jul 2015 14:00:00 GMT',
'd:getetag': '"66cfcabd79abb"',
'd:resourcetype': '<d:collection/>',
'oc:id': '00000015oc2d13a6a068',
'oc:fileid': '15',
'oc:permissions': 'RDNVCK',
'oc:size': '100'
},
[
'd:getcontenttype',
'd:getcontentlength'
]
) +
'</d:multistatus>'
);
it('sends REPORT with filter information', function() {
client.getFilteredFiles({
systemTagIds: ['123', '456']
});
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('REPORT');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl);
var body = requestStub.lastCall.args[3];
var doc = (new window.DOMParser()).parseFromString(
body,
'application/xml'
);
var ns = 'http://owncloud.org/ns';
expect(doc.documentElement.localName).toEqual('filter-files');
expect(doc.documentElement.namespaceURI).toEqual(ns);
var filterRoots = doc.getElementsByTagNameNS(ns, 'filter-rules');
var rulesList = filterRoots[0] = doc.getElementsByTagNameNS(ns, 'systemtag');
expect(rulesList.length).toEqual(2);
expect(rulesList[0].localName).toEqual('systemtag');
expect(rulesList[0].namespaceURI).toEqual(ns);
expect(rulesList[0].textContent).toEqual('123');
expect(rulesList[1].localName).toEqual('systemtag');
expect(rulesList[1].namespaceURI).toEqual(ns);
expect(rulesList[1].textContent).toEqual('456');
});
it('sends REPORT with explicit properties to filter file list', function() {
client.getFilteredFiles({
systemTagIds: ['123', '456']
});
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('REPORT');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl);
var props = getRequestedProperties(requestStub.lastCall.args[3]);
expect(props).toContain('{DAV:}getlastmodified');
expect(props).toContain('{DAV:}getcontentlength');
expect(props).toContain('{DAV:}getcontenttype');
expect(props).toContain('{DAV:}getetag');
expect(props).toContain('{DAV:}resourcetype');
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({
systemTagIds: ['123', '456']
});
expect(requestStub.calledOnce).toEqual(true);
requestDeferred.resolve({
status: 207,
body: folderContentsXml
});
promise.then(function(status, response) {
expect(status).toEqual(207);
expect(_.isArray(response)).toEqual(true);
// returns all entries
expect(response.length).toEqual(3);
// file entry
var info = response[0];
expect(info instanceof OC.Files.FileInfo).toEqual(true);
expect(info.id).toEqual(11);
// file entry
info = response[1];
expect(info instanceof OC.Files.FileInfo).toEqual(true);
expect(info.id).toEqual(51);
// sub entry
info = response[2];
expect(info instanceof OC.Files.FileInfo).toEqual(true);
expect(info.id).toEqual(15);
});
});
it('throws exception if arguments are missing', function() {
var thrown = null;
try {
client.getFilteredFiles({});
} catch (e) {
thrown = true;
}
expect(thrown).toEqual(true);
});
});
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" xmlns:nc="http://nextcloud.org/ns">' +
makeResponseBlock(
'/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/',
{
'd:getlastmodified': 'Fri, 10 Jul 2015 10:00:05 GMT',
'd:getetag': '"56cfcabd79abb"',
'd:resourcetype': '<d:collection/>',
'oc:id': '00000011oc2d13a6a068',
'oc:fileid': '11',
'oc:permissions': 'GRDNVCK',
'oc:size': '120',
'nc:is-encrypted': '1'
},
[
'd:getcontenttype',
'd:getcontentlength'
]
) +
'</d:multistatus>'
);
it('sends PROPFIND with zero depth to get single file info', function() {
client.getFileInfo('path/to space/文件夹');
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');
var props = getRequestedProperties(requestStub.lastCall.args[3]);
expect(props).toContain('{DAV:}getlastmodified');
expect(props).toContain('{DAV:}getcontentlength');
expect(props).toContain('{DAV:}getcontenttype');
expect(props).toContain('{DAV:}getetag');
expect(props).toContain('{DAV:}resourcetype');
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/文件夹');
expect(requestStub.calledOnce).toEqual(true);
requestDeferred.resolve({
status: 207,
body: responseXml
});
promise.then(function(status, response) {
expect(status).toEqual(207);
expect(_.isArray(response)).toEqual(false);
var info = response;
expect(info instanceof OC.Files.FileInfo).toEqual(true);
expect(info.id).toEqual(11);
expect(info.path).toEqual('/path/to space');
expect(info.name).toEqual('文件夹');
expect(info.permissions).toEqual(31);
expect(info.size).toEqual(120);
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() {
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">' +
makeResponseBlock(
'/owncloud/remote.php/webdav/in%20root',
{
'd:getlastmodified': 'Fri, 10 Jul 2015 10:00:05 GMT',
'd:getetag': '"56cfcabd79abb"',
'd:resourcetype': '<d:collection/>',
'oc:id': '00000011oc2d13a6a068',
'oc:fileid': '11',
'oc:permissions': 'GRDNVCK',
'oc:size': '120'
},
[
'd:getcontenttype',
'd:getcontentlength'
]
) +
'</d:multistatus>'
);
var promise = client.getFileInfo('in root');
expect(requestStub.calledOnce).toEqual(true);
requestDeferred.resolve({
status: 207,
body: responseXml
});
promise.then(function(status, response) {
expect(status).toEqual(207);
expect(_.isArray(response)).toEqual(false);
var info = response;
expect(info instanceof OC.Files.FileInfo).toEqual(true);
expect(info.id).toEqual(11);
expect(info.path).toEqual('/');
expect(info.name).toEqual('in root');
expect(info.permissions).toEqual(31);
expect(info.size).toEqual(120);
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() {
var promise = client.getFileInfo('path/to space/文件夹');
respondAndCheckError(promise, 404);
});
it('throws exception if arguments are missing', function() {
// TODO
});
});
describe('permissions', function() {
function getFileInfoWithPermission(webdavPerm, isFile) {
var props = {
'd:getlastmodified': 'Fri, 10 Jul 2015 13:38:05 GMT',
'd:getetag': '"559fcabd79a38"',
'd:getcontentlength': 250,
'oc:id': '00000051oc2d13a6a068',
'oc:fileid': '51',
'oc:permissions': webdavPerm,
};
if (isFile) {
props['d:getcontenttype'] = 'text/plain';
} else {
props['d:resourcetype'] = '<d:collection/>';
}
var def = new $.Deferred();
requestStub.reset();
requestStub.returns(def);
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">' +
makeResponseBlock(
'/owncloud/remote.php/webdav/file.txt',
props
) +
'</d:multistatus>'
);
var promise = client.getFileInfo('file.txt');
expect(requestStub.calledOnce).toEqual(true);
def.resolve({
status: 207,
body: responseXml
});
return promise;
}
function testPermission(permission, isFile, expectedPermissions) {
var promise = getFileInfoWithPermission(permission, isFile);
promise.then(function(status, result) {
expect(result.permissions).toEqual(expectedPermissions);
});
}
function testMountType(permission, isFile, expectedMountType) {
var promise = getFileInfoWithPermission(permission, isFile);
promise.then(function(status, result) {
expect(result.mountType).toEqual(expectedMountType);
});
}
it('properly parses file permissions', function() {
// permission, isFile, expectedPermissions
var testCases = [
['', 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(this, testCase);
});
});
it('properly parses mount types', function() {
var testCases = [
['CKGWDR', false, null],
['M', false, 'external'],
['S', false, 'shared'],
['SM', false, 'shared']
];
_.each(testCases, function(testCase) {
return testMountType.apply(this, testCase);
});
});
});
describe('get file contents', function() {
it('returns file contents', function() {
var promise = client.getFileContents('path/to space/文件夹/One.txt');
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('GET');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl + 'path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/One.txt');
requestDeferred.resolve({
status: 200,
body: 'some contents'
});
promise.then(function(status, response) {
expect(status).toEqual(200);
expect(response).toEqual('some contents');
});
});
it('rejects promise when an error occurred', function() {
var promise = client.getFileContents('path/to space/文件夹/One.txt');
respondAndCheckError(promise, 409);
});
it('throws exception if arguments are missing', function() {
// TODO
});
});
describe('put file contents', function() {
it('sends PUT with file contents', function() {
var promise = client.putFileContents(
'path/to space/文件夹/One.txt',
'some contents'
);
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('PUT');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl + 'path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/One.txt');
expect(requestStub.lastCall.args[2]['If-None-Match']).toEqual('*');
expect(requestStub.lastCall.args[2]['Content-Type']).toEqual('text/plain;charset=utf-8');
expect(requestStub.lastCall.args[3]).toEqual('some contents');
respondAndCheckStatus(promise, 201);
});
it('sends PUT with file contents with headers matching options', function() {
var promise = client.putFileContents(
'path/to space/文件夹/One.txt',
'some contents',
{
overwrite: false,
contentType: 'text/markdown'
}
);
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('PUT');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl + 'path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/One.txt');
expect(requestStub.lastCall.args[2]['If-None-Match']).not.toBeDefined();
expect(requestStub.lastCall.args[2]['Content-Type']).toEqual('text/markdown');
expect(requestStub.lastCall.args[3]).toEqual('some contents');
respondAndCheckStatus(promise, 201);
});
it('rejects promise when an error occurred', function() {
var promise = client.putFileContents(
'path/to space/文件夹/One.txt',
'some contents'
);
respondAndCheckError(promise, 409);
});
it('throws exception if arguments are missing', function() {
// TODO
});
});
describe('create directory', function() {
it('sends MKCOL with specified path', function() {
var promise = client.createDirectory('path/to space/文件夹/new dir');
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('MKCOL');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl + 'path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/new%20dir');
respondAndCheckStatus(promise, 201);
});
it('rejects promise when an error occurred', function() {
var promise = client.createDirectory('path/to space/文件夹/new dir');
respondAndCheckError(promise, 404);
});
it('throws exception if arguments are missing', function() {
// TODO
});
});
describe('deletion', function() {
it('sends DELETE with specified path', function() {
var promise = client.remove('path/to space/文件夹');
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('DELETE');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl + 'path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9');
respondAndCheckStatus(promise, 201);
});
it('rejects promise when an error occurred', function() {
var promise = client.remove('path/to space/文件夹');
respondAndCheckError(promise, 404);
});
it('throws exception if arguments are missing', function() {
// TODO
});
});
describe('move', function() {
it('sends MOVE with specified paths with fail on overwrite by default', function() {
var promise = client.move(
'path/to space/文件夹',
'path/to space/anotherdir/文件夹'
);
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('MOVE');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl + 'path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9');
expect(requestStub.lastCall.args[2].Destination)
.toEqual(baseUrl + 'path/to%20space/anotherdir/%E6%96%87%E4%BB%B6%E5%A4%B9');
expect(requestStub.lastCall.args[2].Overwrite)
.toEqual('F');
respondAndCheckStatus(promise, 201);
});
it('sends MOVE with silent overwrite mode when specified', function() {
var promise = client.move(
'path/to space/文件夹',
'path/to space/anotherdir/文件夹',
{allowOverwrite: true}
);
expect(requestStub.calledOnce).toEqual(true);
expect(requestStub.lastCall.args[0]).toEqual('MOVE');
expect(requestStub.lastCall.args[1]).toEqual(baseUrl + 'path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9');
expect(requestStub.lastCall.args[2].Destination)
.toEqual(baseUrl + 'path/to%20space/anotherdir/%E6%96%87%E4%BB%B6%E5%A4%B9');
expect(requestStub.lastCall.args[2].Overwrite)
.not.toBeDefined();
respondAndCheckStatus(promise, 201);
});
it('rejects promise when an error occurred', function() {
var promise = client.move(
'path/to space/文件夹',
'path/to space/anotherdir/文件夹',
{allowOverwrite: true}
);
respondAndCheckError(promise, 404);
});
it('throws exception if arguments are missing', function() {
// TODO
});
});
});
@@ -0,0 +1,225 @@
/**
* 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.
*
*/
describe('jquery.avatar tests', function() {
var $div;
var devicePixelRatio;
beforeEach(function() {
$('#testArea').append($('<div id="avatardiv">'));
$div = $('#avatardiv');
devicePixelRatio = window.devicePixelRatio;
window.devicePixelRatio = 1;
spyOn(window, 'Image').and.returnValue({
onload: function() {
},
onerror: function() {
}
});
});
afterEach(function() {
$div.remove();
window.devicePixelRatio = devicePixelRatio;
});
describe('size', function() {
it('undefined', function() {
$div.avatar('foo');
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(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(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(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('?');
expect($div.css).toHaveBeenCalledWith('background-color', '#b9b9b9');
});
describe('no avatar', function() {
it('show placeholder for existing user', function() {
spyOn($div, 'imageplaceholder');
$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');
expect(window.Image).toHaveBeenCalled();
window.Image().onerror();
expect($div.imageplaceholder).toHaveBeenCalledWith('?');
expect($div.css).toHaveBeenCalledWith('background-color', '#b9b9b9');
});
it('show no placeholder is ignored', function() {
spyOn($div, 'imageplaceholder');
spyOn($div, 'css');
$div.avatar('foo', undefined, undefined, true);
expect(window.Image).toHaveBeenCalled();
window.Image().onerror();
expect($div.imageplaceholder).toHaveBeenCalledWith('?');
expect($div.css).toHaveBeenCalledWith('background-color', '#b9b9b9');
});
});
describe('url generation', function() {
beforeEach(function() {
window.devicePixelRatio = 1;
});
it('default', function() {
window.devicePixelRatio = 1;
$div.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(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(window.Image).toHaveBeenCalled();
expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/61');
});
});
describe('valid avatar', function() {
beforeEach(function() {
window.devicePixelRatio = 1;
});
it('default (no ie8 fix)', function() {
$div.avatar('foo', 32);
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');
});
it('default high DPI icon', function() {
window.devicePixelRatio = 1.9;
$div.avatar('foo', 32);
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/61');
});
it('with ie8 fix (ignored)', function() {
$div.avatar('foo', 32, true);
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');
});
it('unhide div', function() {
$div.hide();
$div.avatar('foo', 32);
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');
});
it('callback called', function() {
var observer = {callback: function() { dump("FOO"); }};
spyOn(observer, 'callback');
$div.avatar('foo', 32, undefined, undefined, function() {
observer.callback();
});
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();
});
});
});
@@ -0,0 +1,240 @@
/**
* Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com>
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/
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);
});
});
});
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2019 Serhii Shliakhov <shlyakhov.up@gmail.com>
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/
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');
});
});
});
@@ -0,0 +1,174 @@
/**
* Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/
describe('OC.L10N tests', function() {
var TEST_APP = 'jsunittestapp';
beforeEach(function() {
window._oc_appswebroots[TEST_APP] = OC.getRootPath() + '/apps3/jsunittestapp';
});
afterEach(function() {
OC.L10N._unregister(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}',
'sunny': 'sonnig'
});
});
it('returns untranslated text when no bundle exists', function() {
OC.L10N._unregister(TEST_APP);
expect(t(TEST_APP, 'unknown text')).toEqual('unknown text');
});
it('returns untranslated text when no key exists', function() {
expect(t(TEST_APP, 'unknown text')).toEqual('unknown text');
});
it('returns translated text when key exists', function() {
expect(t(TEST_APP, 'Hello world!')).toEqual('Hallo Welt!');
});
it('returns translated text with placeholder', function() {
expect(
t(TEST_APP, 'Hello {name}, the weather is {weather}', {name: 'Steve', weather: t(TEST_APP, 'sunny')})
).toEqual('Hallo Steve, das Wetter ist sonnig');
});
it('returns text with escaped placeholder', function() {
expect(
t(TEST_APP, 'Hello {name}', {name: '<strong>Steve</strong>'})
).toEqual('Hello &lt;strong&gt;Steve&lt;/strong&gt;');
});
it('returns text with not escaped placeholder', function() {
expect(
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',
'new': 'neu'
});
expect(t(TEST_APP, 'sunny')).toEqual('sonnig');
expect(t(TEST_APP, 'new')).toEqual('neu');
});
});
describe('plurals', function() {
function checkPlurals() {
expect(
n(TEST_APP, 'download %n file', 'download %n files', 0)
).toEqual('0 Dateien herunterladen');
expect(
n(TEST_APP, 'download %n file', 'download %n files', 1)
).toEqual('1 Datei herunterladen');
expect(
n(TEST_APP, 'download %n file', 'download %n files', 2)
).toEqual('2 Dateien herunterladen');
expect(
n(TEST_APP, 'download %n file', 'download %n files', 1024)
).toEqual('1024 Dateien herunterladen');
}
it('generates plural for default text when translation does not exist', function() {
spyOn(console, 'warn');
OC.L10N.register(TEST_APP, {
});
expect(
n(TEST_APP, 'download %n file', 'download %n files', 0)
).toEqual('download 0 files');
expect(
n(TEST_APP, 'download %n file', 'download %n files', 1)
).toEqual('download 1 file');
expect(
n(TEST_APP, 'download %n file', 'download %n files', 2)
).toEqual('download 2 files');
expect(
n(TEST_APP, 'download %n file', 'download %n files', 1024)
).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();
});
});
describe('async loading of translations', function() {
afterEach(() => {
document.documentElement.removeAttribute('data-locale')
})
it('loads bundle for given app and calls callback', function(done) {
document.documentElement.setAttribute('data-locale', 'zh_CN')
var callbackStub = sinon.stub();
var promiseStub = sinon.stub();
var loading = OC.L10N.load(TEST_APP, callbackStub);
expect(callbackStub.notCalled).toEqual(true);
var req = fakeServer.requests[0];
loading
.then(promiseStub)
.then(function() {
expect(fakeServer.requests.length).toEqual(1);
expect(req.url).toEqual(
OC.getRootPath() + '/apps3/' + TEST_APP + '/l10n/zh_CN.json'
);
expect(callbackStub.calledOnce).toEqual(true);
expect(promiseStub.calledOnce).toEqual(true);
expect(t(TEST_APP, 'Hello world!')).toEqual('你好世界!');
})
.then(done)
.catch(e => expect(e).toBe('No error expected!'));
expect(promiseStub.notCalled).toEqual(true);
req.respond(
200,
{ 'Content-Type': 'application/json' },
JSON.stringify({
translations: {'Hello world!': '你好世界!'},
pluralForm: 'nplurals=2; plural=(n != 1);'
})
);
});
it('calls callback if translation already available', function(done) {
var callbackStub = sinon.stub();
spyOn(console, 'warn');
OC.L10N.register(TEST_APP, {
'Hello world!': 'Hallo Welt!'
});
OC.L10N.load(TEST_APP, callbackStub)
.then(function() {
expect(callbackStub.calledOnce).toEqual(true);
expect(fakeServer.requests.length).toEqual(0);
})
.then(done);
});
it('calls callback if locale is en', function(done) {
var callbackStub = sinon.stub();
OC.L10N.load(TEST_APP, callbackStub)
.then(function() {
expect(callbackStub.calledOnce).toEqual(true);
expect(fakeServer.requests.length).toEqual(0);
})
.then(done)
.catch(done);
});
});
});
@@ -0,0 +1,151 @@
/**
* @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/>
*
*/
describe('MimeType tests', function() {
var _files;
var _aliases;
var _theme;
beforeEach(function() {
_files = OC.MimeTypeList.files;
_aliases = OC.MimeTypeList.aliases;
_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'];
});
afterEach(function() {
OC.MimeTypeList.files = _files;
OC.MimeTypeList.aliases = _aliases;
OC.MimeTypeList.themes.abc = _theme;
});
describe('_getFile', function() {
it('returns the correct icon for "dir"', function() {
var res = OC.MimeType._getFile('dir', OC.MimeTypeList.files);
expect(res).toEqual('folder');
});
it('returns the correct icon for "dir-shared"', function() {
var res = OC.MimeType._getFile('dir-shared', OC.MimeTypeList.files);
expect(res).toEqual('folder-shared');
});
it('returns the correct icon for "dir-external"', function() {
var res = OC.MimeType._getFile('dir-external', OC.MimeTypeList.files);
expect(res).toEqual('folder-external');
});
it('returns the correct icon for a mimetype for which we have an icon', function() {
var res = OC.MimeType._getFile('foo/bar', OC.MimeTypeList.files);
expect(res).toEqual('foo-bar');
});
it('returns the correct icon for a mimetype for which we only have a general mimetype icon', function() {
var res = OC.MimeType._getFile('foo/baz', OC.MimeTypeList.files);
expect(res).toEqual('foo');
});
it('return the file mimetype if we have no matching icon but do have a file icon', function() {
var res = OC.MimeType._getFile('foobar', OC.MimeTypeList.files);
expect(res).toEqual('file');
});
it('return null if we do not have a matching icon', function() {
var res = OC.MimeType._getFile('xyz', []);
expect(res).toEqual(null);
});
});
describe('getIconUrl', function() {
describe('no theme', function() {
var _themeFolder;
beforeEach(function() {
_themeFolder = OC.theme.folder;
OC.theme.folder = '';
//Clear mimetypeIcons caches
OC.MimeType._mimeTypeIcons = {};
});
afterEach(function() {
OC.theme.folder = _themeFolder;
});
it('return undefined if the an icon for undefined is requested', function() {
var res = OC.MimeType.getIconUrl(undefined);
expect(res).toEqual(undefined);
});
it('return the url for the mimetype file', function() {
var res = OC.MimeType.getIconUrl('file');
expect(res).toEqual(OC.getRootPath() + '/core/img/filetypes/file.svg');
});
it('test if the cache works correctly', function() {
OC.MimeType._mimeTypeIcons = {};
expect(Object.keys(OC.MimeType._mimeTypeIcons).length).toEqual(0);
var res = OC.MimeType.getIconUrl('dir');
expect(Object.keys(OC.MimeType._mimeTypeIcons).length).toEqual(1);
expect(OC.MimeType._mimeTypeIcons.dir).toEqual(res);
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.getRootPath() + '/core/img/filetypes/foo-bar.svg');
expect(OC.MimeType._mimeTypeIcons['foo/bar']).toEqual(res);
});
});
describe('themes', function() {
var _themeFolder;
beforeEach(function() {
_themeFolder = OC.theme.folder;
OC.theme.folder = 'abc';
//Clear mimetypeIcons caches
OC.MimeType._mimeTypeIcons = {};
});
afterEach(function() {
OC.theme.folder = _themeFolder;
});
it('test if theme path is used if a theme icon is availble', function() {
var res = OC.MimeType.getIconUrl('dir');
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.getRootPath() + '/core/img/filetypes/folder-shared.svg');
});
});
});
});
@@ -0,0 +1,410 @@
/**
* 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 dav */
describe('Backbone Webdav extension', function() {
var davClientRequestStub;
var davClientPropPatchStub;
var davClientPropFindStub;
var deferredRequest;
beforeEach(function() {
deferredRequest = $.Deferred();
davClientRequestStub = sinon.stub(dav.Client.prototype, 'request');
davClientPropPatchStub = sinon.stub(dav.Client.prototype, 'propPatch');
davClientPropFindStub = sinon.stub(dav.Client.prototype, 'propFind');
davClientRequestStub.returns(deferredRequest.promise());
davClientPropPatchStub.returns(deferredRequest.promise());
davClientPropFindStub.returns(deferredRequest.promise());
});
afterEach(function() {
davClientRequestStub.restore();
davClientPropPatchStub.restore();
davClientPropFindStub.restore();
});
describe('collections', function() {
var TestModel;
var TestCollection;
beforeEach(function() {
TestModel = OC.Backbone.Model.extend({
sync: OC.Backbone.davSync,
davProperties: {
'firstName': '{http://owncloud.org/ns}first-name',
'lastName': '{http://owncloud.org/ns}last-name',
'age': '{http://owncloud.org/ns}age',
'married': '{http://owncloud.org/ns}married'
},
parse: function(data) {
return {
id: data.id,
firstName: data.firstName,
lastName: data.lastName,
age: parseInt(data.age, 10),
married: data.married === 'true' || data.married === true
};
}
});
TestCollection = OC.Backbone.Collection.extend({
sync: OC.Backbone.davSync,
model: TestModel,
url: 'http://example.com/owncloud/remote.php/test/'
});
});
it('makes a POST request to create model into collection', function(done) {
var collection = new TestCollection();
var model = collection.create({
firstName: 'Hello',
lastName: 'World'
});
expect(davClientRequestStub.calledOnce).toEqual(true);
expect(davClientRequestStub.getCall(0).args[0])
.toEqual('POST');
expect(davClientRequestStub.getCall(0).args[1])
.toEqual('http://example.com/owncloud/remote.php/test/');
expect(davClientRequestStub.getCall(0).args[2]['Content-Type'])
.toEqual('application/json');
expect(davClientRequestStub.getCall(0).args[2]['X-Requested-With'])
.toEqual('XMLHttpRequest');
expect(davClientRequestStub.getCall(0).args[3])
.toEqual(JSON.stringify({
'firstName': 'Hello',
'lastName': 'World'
}));
var responseHeaderStub = sinon.stub()
.withArgs('Content-Location')
.returns('http://example.com/owncloud/remote.php/test/123');
deferredRequest.resolve({
status: 201,
body: '',
xhr: {
getResponseHeader: responseHeaderStub
}
});
setTimeout(function() {
expect(model.id).toEqual('123');
done();
}, 0)
});
it('uses PROPFIND to retrieve collection', function(done) {
var successStub = sinon.stub();
var errorStub = sinon.stub();
var collection = new TestCollection();
collection.fetch({
success: successStub,
error: errorStub
});
expect(davClientPropFindStub.calledOnce).toEqual(true);
expect(davClientPropFindStub.getCall(0).args[0])
.toEqual('http://example.com/owncloud/remote.php/test/');
expect(davClientPropFindStub.getCall(0).args[1])
.toEqual([
'{http://owncloud.org/ns}first-name',
'{http://owncloud.org/ns}last-name',
'{http://owncloud.org/ns}age',
'{http://owncloud.org/ns}married'
]);
expect(davClientPropFindStub.getCall(0).args[2])
.toEqual(1);
expect(davClientPropFindStub.getCall(0).args[3]['X-Requested-With'])
.toEqual('XMLHttpRequest');
deferredRequest.resolve({
status: 207,
body: [
// root element
{
href: 'http://example.org/owncloud/remote.php/test/',
propStat: []
},
// first model
{
href: 'http://example.org/owncloud/remote.php/test/123',
propStat: [{
status: 'HTTP/1.1 200 OK',
properties: {
'{http://owncloud.org/ns}first-name': 'Hello',
'{http://owncloud.org/ns}last-name': 'World'
}
}]
},
// second model
{
href: 'http://example.org/owncloud/remote.php/test/456',
propStat: [{
status: 'HTTP/1.1 200 OK',
properties: {
'{http://owncloud.org/ns}first-name': 'Test',
'{http://owncloud.org/ns}last-name': 'Person'
}
}]
}
]
});
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');
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);
done();
}, 0)
});
function testMethodError(doCall, done) {
var successStub = sinon.stub();
var errorStub = sinon.stub();
doCall(successStub, errorStub);
deferredRequest.resolve({
status: 404,
body: ''
});
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(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(done) {
testMethodError(function(success, error) {
var collection = new TestCollection();
collection.create({
firstName: 'Hello',
lastName: 'World'
}, {
success: success,
error: error
});
}, done);
});
});
describe('models', function() {
var TestModel;
beforeEach(function() {
TestModel = OC.Backbone.Model.extend({
sync: OC.Backbone.davSync,
davProperties: {
'firstName': '{http://owncloud.org/ns}first-name',
'lastName': '{http://owncloud.org/ns}last-name',
'age': '{http://owncloud.org/ns}age', // int
'married': '{http://owncloud.org/ns}married', // bool
},
url: function() {
return 'http://example.com/owncloud/remote.php/test/' + this.id;
},
parse: function(data) {
return {
id: data.id,
firstName: data.firstName,
lastName: data.lastName,
age: parseInt(data.age, 10),
married: data.married === 'true' || data.married === true
};
}
});
});
it('makes a PROPPATCH request to update model', function() {
var model = new TestModel({
id: '123',
firstName: 'Hello',
lastName: 'World',
age: 32,
married: false
});
model.save({
firstName: 'Hey',
age: 33,
married: true
});
expect(davClientPropPatchStub.calledOnce).toEqual(true);
expect(davClientPropPatchStub.getCall(0).args[0])
.toEqual('http://example.com/owncloud/remote.php/test/123');
expect(davClientPropPatchStub.getCall(0).args[1])
.toEqual({
'{http://owncloud.org/ns}first-name': 'Hey',
'{http://owncloud.org/ns}age': '33',
'{http://owncloud.org/ns}married': 'true'
});
expect(davClientPropPatchStub.getCall(0).args[2]['X-Requested-With'])
.toEqual('XMLHttpRequest');
deferredRequest.resolve({
status: 201,
body: ''
});
expect(model.id).toEqual('123');
expect(model.get('firstName')).toEqual('Hey');
expect(model.get('age')).toEqual(33);
expect(model.get('married')).toEqual(true);
});
it('uses PROPFIND to fetch single model', function(done) {
var model = new TestModel({
id: '123'
});
model.fetch();
expect(davClientPropFindStub.calledOnce).toEqual(true);
expect(davClientPropFindStub.getCall(0).args[0])
.toEqual('http://example.com/owncloud/remote.php/test/123');
expect(davClientPropFindStub.getCall(0).args[1])
.toEqual([
'{http://owncloud.org/ns}first-name',
'{http://owncloud.org/ns}last-name',
'{http://owncloud.org/ns}age',
'{http://owncloud.org/ns}married'
]);
expect(davClientPropFindStub.getCall(0).args[2])
.toEqual(0);
expect(davClientPropFindStub.getCall(0).args[3]['X-Requested-With'])
.toEqual('XMLHttpRequest');
deferredRequest.resolve({
status: 207,
body: {
href: 'http://example.org/owncloud/remote.php/test/123',
propStat: [{
status: 'HTTP/1.1 200 OK',
properties: {
'{http://owncloud.org/ns}first-name': 'Hello',
'{http://owncloud.org/ns}last-name': 'World',
'{http://owncloud.org/ns}age': '35',
'{http://owncloud.org/ns}married': '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({
id: '123',
firstName: 'Hello',
lastName: 'World'
});
model.destroy();
expect(davClientRequestStub.calledOnce).toEqual(true);
expect(davClientRequestStub.getCall(0).args[0])
.toEqual('DELETE');
expect(davClientRequestStub.getCall(0).args[1])
.toEqual('http://example.com/owncloud/remote.php/test/123');
expect(davClientRequestStub.getCall(0).args[2]['X-Requested-With'])
.toEqual('XMLHttpRequest');
expect(davClientRequestStub.getCall(0).args[3])
.toBeFalsy();
deferredRequest.resolve({
status: 200,
body: ''
});
});
function testMethodError(doCall, done) {
var successStub = sinon.stub();
var errorStub = sinon.stub();
doCall(successStub, errorStub);
deferredRequest.resolve({
status: 404,
body: ''
});
setTimeout(function() {
expect(successStub.notCalled).toEqual(true);
expect(errorStub.calledOnce).toEqual(true);
done();
});
}
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(done) {
testMethodError(function(success, error) {
var model = new TestModel();
model.save({
firstName: 'Hey'
}, {
success: success,
error: error
});
}, done);
});
});
});
@@ -0,0 +1,51 @@
/**
* @copyright 2018 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/>.
*
*/
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);
});
});
});
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,69 @@
/**
* 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/>.
*
*/
describe('OC.SystemTags tests', function() {
it('describes non existing tag', function() {
var $return = OC.SystemTags.getDescriptiveTag('23');
expect($return.textContent).toEqual('Non-existing tag #23');
expect($return.classList.contains('non-existing-tag')).toEqual(true);
});
it('describes SystemTagModel', function() {
var tag = new OC.SystemTags.SystemTagModel({
id: 23,
name: 'Twenty Three',
userAssignable: true,
userVisible: true
});
var $return = OC.SystemTags.getDescriptiveTag(tag);
expect($return.textContent).toEqual('Twenty Three');
expect($return.classList.contains('non-existing-tag')).toEqual(false);
});
it('describes JSON tag object', function() {
var $return = OC.SystemTags.getDescriptiveTag({
id: 42,
name: 'Fourty Two',
userAssignable: true,
userVisible: true
});
expect($return.textContent).toEqual('Fourty Two');
expect($return.classList.contains('non-existing-tag')).toEqual(false);
});
it('scope', function() {
function testScope(userVisible, userAssignable, expectedText) {
var $return = OC.SystemTags.getDescriptiveTag({
id: 42,
name: 'Fourty Two',
userAssignable: userAssignable,
userVisible: userVisible
});
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 (Restricted)');
});
});
@@ -0,0 +1,84 @@
/**
* 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/>.
*
*/
describe('OC.SystemTags.SystemTagsCollection tests', function() {
var collection;
beforeEach(function() {
collection = new OC.SystemTags.SystemTagsCollection();
});
it('fetches only once, until reset', function() {
var syncStub = sinon.stub(collection, 'sync');
var callback = sinon.stub();
var callback2 = sinon.stub();
var callback3 = sinon.stub();
var eventHandler = sinon.stub();
collection.on('sync', eventHandler);
collection.fetch({
success: callback
});
expect(callback.notCalled).toEqual(true);
expect(syncStub.calledOnce).toEqual(true);
expect(eventHandler.notCalled).toEqual(true);
syncStub.yieldTo('success', collection);
expect(callback.calledOnce).toEqual(true);
expect(callback.firstCall.args[0]).toEqual(collection);
expect(eventHandler.calledOnce).toEqual(true);
expect(eventHandler.firstCall.args[0]).toEqual(collection);
collection.fetch({
success: callback2
});
expect(eventHandler.calledTwice).toEqual(true);
expect(eventHandler.secondCall.args[0]).toEqual(collection);
// not re-called
expect(syncStub.calledOnce).toEqual(true);
expect(callback.calledOnce).toEqual(true);
expect(callback2.calledOnce).toEqual(true);
expect(callback2.firstCall.args[0]).toEqual(collection);
expect(collection.fetched).toEqual(true);
collection.reset();
expect(collection.fetched).toEqual(false);
collection.fetch({
success: callback3
});
expect(syncStub.calledTwice).toEqual(true);
syncStub.yieldTo('success', collection);
expect(callback3.calledOnce).toEqual(true);
expect(callback3.firstCall.args[0]).toEqual(collection);
syncStub.restore();
});
});
@@ -0,0 +1,629 @@
/**
* 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/>.
*
*/
describe('OC.SystemTags.SystemTagsInputField tests', function() {
var view, select2Stub, clock;
beforeEach(function() {
clock = sinon.useFakeTimers();
var $container = $('<div class="testInputContainer"></div>');
select2Stub = sinon.stub($.fn, 'select2');
select2Stub.returnsThis();
$('#testArea').append($container);
});
afterEach(function() {
select2Stub.restore();
OC.SystemTags.collection.reset();
clock.restore();
view.remove();
view = undefined;
});
describe('general behavior', function() {
var $dropdown;
beforeEach(function() {
view = new OC.SystemTags.SystemTagsInputField();
$('.testInputContainer').append(view.$el);
$dropdown = $('<div class="select2-dropdown"></div>');
select2Stub.withArgs('dropdown').returns($dropdown);
$('#testArea').append($dropdown);
view.render();
});
describe('rendering', function() {
it('calls select2 on rendering', function() {
expect(view.$el.find('input[name=tags]').length).toEqual(1);
expect(select2Stub.called).toEqual(true);
});
it('formatResult renders rename button', function() {
var opts = select2Stub.getCall(0).args[0];
var $el = $(opts.formatResult({id: '1', name: 'test'}));
expect($el.find('.rename').length).toEqual(1);
});
});
describe('tag selection', function() {
beforeEach(function() {
var $el = view.$el.find('input');
$el.val('1');
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, canAssign: false}),
]);
});
it('does not create dummy tag when user types non-matching name', function() {
var opts = select2Stub.getCall(0).args[0];
var result = opts.createSearchChoice('abc');
expect(result).not.toBeDefined();
});
it('creates dummy tag when user types non-matching name', function() {
var opts = select2Stub.getCall(0).args[0];
var result = opts.createSearchChoice('abnew');
expect(result.id).toEqual(-1);
expect(result.name).toEqual('abnew');
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];
var result = opts.createSearchChoice('ab');
expect(result.id).toEqual(-1);
expect(result.name).toEqual('ab');
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();
view.on('select', selectHandler);
var createStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'create');
view.$el.find('input').trigger(new $.Event('select2-selecting', {
object: {
id: -1,
name: 'newname',
isNew: true
}
}));
expect(createStub.calledOnce).toEqual(true);
expect(createStub.getCall(0).args[0]).toEqual({
name: 'newname',
userVisible: true,
userAssignable: true,
canAssign: true
});
var newModel = new OC.SystemTags.SystemTagModel({
id: '123',
name: 'newname',
userVisible: true,
userAssignable: true,
canAssign: true
});
// not called yet
expect(selectHandler.notCalled).toEqual(true);
select2Stub.withArgs('data').returns([{
id: '1',
name: 'abc'
}]);
createStub.yieldTo('success', newModel);
expect(select2Stub.lastCall.args[0]).toEqual('data');
expect(select2Stub.lastCall.args[1]).toEqual([{
id: '1',
name: 'abc'
},
newModel.toJSON()
]);
expect(selectHandler.calledOnce).toEqual(true);
expect(selectHandler.getCall(0).args[0]).toEqual(newModel);
createStub.restore();
});
it('triggers select event after selecting an existing tag', function() {
var selectHandler = sinon.stub();
view.on('select', selectHandler);
view.$el.find('input').trigger(new $.Event('select2-selecting', {
object: {
id: '2',
name: 'def'
}
}));
expect(selectHandler.calledOnce).toEqual(true);
expect(selectHandler.getCall(0).args[0]).toEqual(view.collection.get('2'));
});
it('triggers deselect event after deselecting an existing tag', function() {
var selectHandler = sinon.stub();
view.on('deselect', selectHandler);
view.$el.find('input').trigger(new $.Event('select2-removing', {
choice: {
id: '2',
name: 'def'
}
}));
expect(selectHandler.calledOnce).toEqual(true);
expect(selectHandler.getCall(0).args[0]).toEqual('2');
});
it('triggers select event and still adds to list even in case of conflict', function() {
var selectHandler = sinon.stub();
view.on('select', selectHandler);
var fetchStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'fetch');
var createStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'create');
view.$el.find('input').trigger(new $.Event('select2-selecting', {
object: {
id: -1,
name: 'newname',
isNew: true
}
}));
expect(createStub.calledOnce).toEqual(true);
expect(createStub.getCall(0).args[0]).toEqual({
name: 'newname',
userVisible: true,
userAssignable: true,
canAssign: true
});
var newModel = new OC.SystemTags.SystemTagModel({
id: '123',
name: 'newname',
userVisible: true,
userAssignable: true
});
// not called yet
expect(selectHandler.notCalled).toEqual(true);
select2Stub.withArgs('data').returns([{
id: '1',
name: 'abc'
}]);
// simulate conflict response for tag creation
createStub.yieldTo('error', view.collection, {status: 409});
// at this point it fetches from the server
expect(fetchStub.calledOnce).toEqual(true);
// simulate fetch result by adding model to the collection
view.collection.add(newModel);
fetchStub.yieldTo('success', view.collection);
expect(select2Stub.lastCall.args[0]).toEqual('data');
expect(select2Stub.lastCall.args[1]).toEqual([{
id: '1',
name: 'abc'
},
newModel.toJSON()
]);
// select event still called
expect(selectHandler.calledOnce).toEqual(true);
expect(selectHandler.getCall(0).args[0]).toEqual(newModel);
createStub.restore();
fetchStub.restore();
});
});
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('displays rename form when clicking rename', function() {
$dropdown.find('.rename').mouseup();
expect($dropdown.find('form.systemtags-rename-form').length).toEqual(1);
expect($dropdown.find('form.systemtags-rename-form input').val()).toEqual('abc');
});
it('renames model and submits change when submitting form', function() {
var saveStub = sinon.stub(OC.SystemTags.SystemTagModel.prototype, 'save');
$dropdown.find('.rename').mouseup();
$dropdown.find('form input').val('abc_renamed');
$dropdown.find('form').trigger(new $.Event('submit'));
expect(saveStub.calledOnce).toEqual(true);
expect(saveStub.getCall(0).args[0]).toEqual({'name': 'abc_renamed'});
expect($dropdown.find('.label').text()).toEqual('abc_renamed');
expect($dropdown.find('form').length).toEqual(0);
saveStub.restore();
});
});
describe('setting data', function() {
it('sets value when calling setValues', function() {
var vals = ['1', '2'];
view.setValues(vals);
expect(select2Stub.lastCall.args[0]).toEqual('val');
expect(select2Stub.lastCall.args[1]).toEqual(vals);
});
it('sets data when calling setData', function() {
var vals = [{id: '1', name: 'test1'}, {id: '2', name: 'test2'}];
view.setData(vals);
expect(select2Stub.lastCall.args[0]).toEqual('data');
expect(select2Stub.lastCall.args[1]).toEqual(vals);
});
});
});
describe('as admin', function() {
var $dropdown;
beforeEach(function() {
view = new OC.SystemTags.SystemTagsInputField({
isAdmin: true
});
$('.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)');
});
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)');
});
describe('initSelection', function() {
var fetchStub;
var testTags;
beforeEach(function() {
fetchStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'fetch');
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, canAssign: false}),
new OC.SystemTags.SystemTagModel({id: '4', name: 'test4', userAssignable: false, canAssign: true})
];
});
afterEach(function() {
fetchStub.restore();
});
it('grabs values from the full collection', function() {
var $el = view.$el.find('input');
$el.val('1,3,4');
var opts = select2Stub.getCall(0).args[0];
var callback = sinon.stub();
opts.initSelection($el, callback);
expect(fetchStub.calledOnce).toEqual(true);
view.collection.add(testTags);
fetchStub.yieldTo('success', view.collection);
expect(callback.calledOnce).toEqual(true);
var models = callback.getCall(0).args[0];
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() {
var fetchStub, opts;
beforeEach(function() {
fetchStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'fetch');
opts = select2Stub.getCall(0).args[0];
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, canAssign: false}),
new OC.SystemTags.SystemTagModel({id: '4', name: 'Deg'}),
]);
});
afterEach(function() {
fetchStub.restore();
});
it('completes results', function() {
var callback = sinon.stub();
opts.query({
term: 'ab',
callback: callback
});
expect(fetchStub.calledOnce).toEqual(true);
fetchStub.yieldTo('success', view.collection);
expect(callback.calledOnce).toEqual(true);
expect(callback.getCall(0).args[0].results).toEqual([
{
id: '1',
name: 'abc',
userVisible: true,
userAssignable: true,
canAssign: true
},
{
id: '3',
name: 'abd',
userVisible: true,
userAssignable: false,
canAssign: false
}
]);
});
it('completes case insensitive', function() {
var callback = sinon.stub();
opts.query({
term: 'de',
callback: callback
});
expect(fetchStub.calledOnce).toEqual(true);
fetchStub.yieldTo('success', view.collection);
expect(callback.calledOnce).toEqual(true);
expect(callback.getCall(0).args[0].results).toEqual([
{
id: '2',
name: 'def',
userVisible: true,
userAssignable: true,
canAssign: true
},
{
id: '4',
name: 'Deg',
userVisible: 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
});
$('.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];
var $el = $(opts.formatResult({id: '1', name: 'test'}));
expect($el.find('.label').text()).toEqual('test');
});
it('formatSelection renders tag name only', function() {
var opts = select2Stub.getCall(0).args[0];
var $el = $(opts.formatSelection({id: '1', name: 'test'}));
expect($el.text().trim()).toEqual('test');
});
describe('initSelection', function() {
var fetchStub;
var testTags;
beforeEach(function() {
fetchStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'fetch');
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, canAssign: false}),
new OC.SystemTags.SystemTagModel({id: '4', name: 'test4', userAssignable: false, canAssign: true})
];
view.render();
});
afterEach(function() {
fetchStub.restore();
});
it('grabs values from the full collection', function() {
var $el = view.$el.find('input');
$el.val('1,3,4');
var opts = select2Stub.getCall(0).args[0];
var callback = sinon.stub();
opts.initSelection($el, callback);
expect(fetchStub.calledOnce).toEqual(true);
view.collection.add(testTags);
fetchStub.yieldTo('success', view.collection);
expect(callback.calledOnce).toEqual(true);
var models = callback.getCall(0).args[0];
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() {
var fetchStub, opts;
beforeEach(function() {
fetchStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'fetch');
view.render();
opts = select2Stub.getCall(0).args[0];
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, canAssign: false}),
new OC.SystemTags.SystemTagModel({id: '4', name: 'Deg'}),
new OC.SystemTags.SystemTagModel({id: '5', name: 'abe', userAssignable: false, canAssign: true})
]);
});
afterEach(function() {
fetchStub.restore();
});
it('completes results excluding non-assignable tags', function() {
var callback = sinon.stub();
opts.query({
term: 'ab',
callback: callback
});
expect(fetchStub.calledOnce).toEqual(true);
fetchStub.yieldTo('success', view.collection);
expect(callback.calledOnce).toEqual(true);
expect(callback.getCall(0).args[0].results).toEqual([
{
id: '1',
name: 'abc',
userVisible: true,
userAssignable: true,
canAssign: true
},
{
id: '5',
name: 'abe',
userVisible: true,
userAssignable: false,
canAssign: true
}
]);
});
it('completes case insensitive', function() {
var callback = sinon.stub();
opts.query({
term: 'de',
callback: callback
});
expect(fetchStub.calledOnce).toEqual(true);
fetchStub.yieldTo('success', view.collection);
expect(callback.calledOnce).toEqual(true);
expect(callback.getCall(0).args[0].results).toEqual([
{
id: '2',
name: 'def',
userVisible: true,
userAssignable: true,
canAssign: true
},
{
id: '4',
name: 'Deg',
userVisible: 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();
});
});
});
});