|
|
/**
|
|
|
* 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() {
|
|
|
let 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
|
|
|
$(document).off('ajaxError.main')
|
|
|
$(document).off('unload.main')
|
|
|
$(document).off('beforeunload.main')
|
|
|
OC._userIsNavigatingAway = false
|
|
|
OC._reloadCalled = false
|
|
|
debounceStub.restore()
|
|
|
})
|
|
|
describe('Base values', function() {
|
|
|
it('Sets webroots', function() {
|
|
|
expect(OC.getRootPath()).toBeDefined()
|
|
|
expect(window._oc_appswebroots).toBeDefined()
|
|
|
})
|
|
|
})
|
|
|
describe('filePath', function() {
|
|
|
beforeEach(function() {
|
|
|
window._oc_webroot = 'http://localhost'
|
|
|
window._oc_appswebroots.files = OC.getRootPath() + '/apps3/files'
|
|
|
})
|
|
|
afterEach(function() {
|
|
|
delete window._oc_appswebroots.files
|
|
|
})
|
|
|
|
|
|
it('Uses a direct link for css and images,', function() {
|
|
|
expect(OC.filePath('core', 'css', 'style.css')).toEqual('http://localhost/core/css/style.css')
|
|
|
expect(OC.filePath('files', 'css', 'style.css')).toEqual('http://localhost/apps3/files/css/style.css')
|
|
|
expect(OC.filePath('core', 'img', 'image.png')).toEqual('http://localhost/core/img/image.png')
|
|
|
expect(OC.filePath('files', 'img', 'image.png')).toEqual('http://localhost/apps3/files/img/image.png')
|
|
|
})
|
|
|
it('Routes PHP files via index.php,', function() {
|
|
|
expect(OC.filePath('core', 'ajax', 'test.php')).toEqual('http://localhost/index.php/core/ajax/test.php')
|
|
|
expect(OC.filePath('files', 'ajax', 'test.php')).toEqual('http://localhost/index.php/apps/files/ajax/test.php')
|
|
|
})
|
|
|
})
|
|
|
describe('Link functions', function() {
|
|
|
const TESTAPP = 'testapp'
|
|
|
const TESTAPP_ROOT = OC.getRootPath() + '/appsx/testapp'
|
|
|
|
|
|
beforeEach(function() {
|
|
|
window._oc_appswebroots[TESTAPP] = TESTAPP_ROOT
|
|
|
})
|
|
|
afterEach(function() {
|
|
|
// restore original array
|
|
|
delete window._oc_appswebroots[TESTAPP]
|
|
|
})
|
|
|
it('Generates correct links for core apps', function() {
|
|
|
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.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.getRootPath() + '/remote.php/webdav')
|
|
|
})
|
|
|
describe('Images', function() {
|
|
|
it('Generates image path with given extension', function() {
|
|
|
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')
|
|
|
})
|
|
|
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')
|
|
|
})
|
|
|
})
|
|
|
})
|
|
|
describe('Query string building', function() {
|
|
|
it('Returns empty string when empty params', function() {
|
|
|
expect(OC.buildQueryString()).toEqual('')
|
|
|
expect(OC.buildQueryString({})).toEqual('')
|
|
|
})
|
|
|
it('Encodes regular query strings', function() {
|
|
|
expect(OC.buildQueryString({
|
|
|
a: 'abc',
|
|
|
b: 'def',
|
|
|
})).toEqual('a=abc&b=def')
|
|
|
})
|
|
|
it('Encodes special characters', function() {
|
|
|
expect(OC.buildQueryString({
|
|
|
unicode: '汉字',
|
|
|
})).toEqual('unicode=%E6%B1%89%E5%AD%97')
|
|
|
expect(OC.buildQueryString({
|
|
|
b: 'spaace value',
|
|
|
'space key': 'normalvalue',
|
|
|
'slash/this': 'amp&ersand',
|
|
|
})).toEqual('b=spaace%20value&space%20key=normalvalue&slash%2Fthis=amp%26ersand')
|
|
|
})
|
|
|
it('Encodes data types and empty values', function() {
|
|
|
expect(OC.buildQueryString({
|
|
|
keywithemptystring: '',
|
|
|
keywithnull: null,
|
|
|
keywithundefined: null,
|
|
|
something: 'else',
|
|
|
})).toEqual('keywithemptystring=&keywithnull&keywithundefined&something=else')
|
|
|
expect(OC.buildQueryString({
|
|
|
booleanfalse: false,
|
|
|
booleantrue: true,
|
|
|
})).toEqual('booleanfalse=false&booleantrue=true')
|
|
|
expect(OC.buildQueryString({
|
|
|
number: 123,
|
|
|
})).toEqual('number=123')
|
|
|
})
|
|
|
})
|
|
|
describe('Parse query string', function() {
|
|
|
it('Parses query string from full URL', function() {
|
|
|
const query = OC.parseQueryString('http://localhost/stuff.php?q=a&b=x')
|
|
|
expect(query).toEqual({ q: 'a', b: 'x' })
|
|
|
})
|
|
|
it('Parses query string from query part alone', function() {
|
|
|
const query = OC.parseQueryString('q=a&b=x')
|
|
|
expect(query).toEqual({ q: 'a', b: 'x' })
|
|
|
})
|
|
|
it('Returns null hash when empty query', function() {
|
|
|
const query = OC.parseQueryString('')
|
|
|
expect(query).toEqual(null)
|
|
|
})
|
|
|
it('Returns empty hash when empty query with question mark', function() {
|
|
|
const query = OC.parseQueryString('?')
|
|
|
expect(query).toEqual({})
|
|
|
})
|
|
|
it('Decodes regular query strings', function() {
|
|
|
const query = OC.parseQueryString('a=abc&b=def')
|
|
|
expect(query).toEqual({
|
|
|
a: 'abc',
|
|
|
b: 'def',
|
|
|
})
|
|
|
})
|
|
|
it('Ignores empty parts', function() {
|
|
|
const query = OC.parseQueryString('&q=a&&b=x&')
|
|
|
expect(query).toEqual({ q: 'a', b: 'x' })
|
|
|
})
|
|
|
it('Ignores lone equal signs', function() {
|
|
|
const query = OC.parseQueryString('&q=a&=&b=x&')
|
|
|
expect(query).toEqual({ q: 'a', b: 'x' })
|
|
|
})
|
|
|
it('Includes extra equal signs in value', function() {
|
|
|
const query = OC.parseQueryString('u=a=x&q=a=b')
|
|
|
expect(query).toEqual({ u: 'a=x', q: 'a=b' })
|
|
|
})
|
|
|
it('Decodes plus as space', function() {
|
|
|
const query = OC.parseQueryString('space+key=space+value')
|
|
|
expect(query).toEqual({ 'space key': 'space value' })
|
|
|
})
|
|
|
it('Decodes special characters', function() {
|
|
|
let query = OC.parseQueryString('unicode=%E6%B1%89%E5%AD%97')
|
|
|
expect(query).toEqual({ unicode: '汉字' })
|
|
|
query = OC.parseQueryString('b=spaace%20value&space%20key=normalvalue&slash%2Fthis=amp%26ersand')
|
|
|
expect(query).toEqual({
|
|
|
b: 'spaace value',
|
|
|
'space key': 'normalvalue',
|
|
|
'slash/this': 'amp&ersand',
|
|
|
})
|
|
|
})
|
|
|
it('Decodes empty values', function() {
|
|
|
const query = OC.parseQueryString('keywithemptystring=&keywithnostring')
|
|
|
expect(query).toEqual({
|
|
|
keywithemptystring: '',
|
|
|
keywithnostring: null,
|
|
|
})
|
|
|
})
|
|
|
it('Does not interpret data types', function() {
|
|
|
const query = OC.parseQueryString('booleanfalse=false&booleantrue=true&number=123')
|
|
|
expect(query).toEqual({
|
|
|
booleanfalse: 'false',
|
|
|
booleantrue: 'true',
|
|
|
number: '123',
|
|
|
})
|
|
|
})
|
|
|
})
|
|
|
describe('Generate Url', function() {
|
|
|
it('returns absolute urls', function() {
|
|
|
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.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.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.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.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.getRootPath() + '/index.php/apps/files/download%7Bfile%7D')
|
|
|
})
|
|
|
})
|
|
|
describe('Util', function() {
|
|
|
describe('computerFileSize', function() {
|
|
|
it('correctly parses file sizes from a human readable formated string', function() {
|
|
|
const data = [
|
|
|
['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 (let i = 0; i < data.length; i++) {
|
|
|
expect(OC.Util.computerFileSize(data[i][0])).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() {
|
|
|
it('strips time from dates', function() {
|
|
|
expect(OC.Util.stripTime(new Date(2014, 2, 24, 15, 4, 45, 24)))
|
|
|
.toEqual(new Date(2014, 2, 24, 0, 0, 0, 0))
|
|
|
})
|
|
|
})
|
|
|
})
|
|
|
describe('naturalSortCompare', function() {
|
|
|
// cit() will skip tests if running on PhantomJS because it has issues with
|
|
|
// localeCompare(). See https://github.com/ariya/phantomjs/issues/11063
|
|
|
//
|
|
|
// Please make sure to run these tests in Chrome/Firefox manually
|
|
|
// to make sure they run.
|
|
|
const cit = window.isPhantom ? xit : it
|
|
|
|
|
|
// must provide the same results as \OCP\Util::naturalSortCompare
|
|
|
it('sorts alphabetically', function() {
|
|
|
const a = [
|
|
|
'def',
|
|
|
'xyz',
|
|
|
'abc',
|
|
|
]
|
|
|
a.sort(OC.Util.naturalSortCompare)
|
|
|
expect(a).toEqual([
|
|
|
'abc',
|
|
|
'def',
|
|
|
'xyz',
|
|
|
])
|
|
|
})
|
|
|
cit('sorts with different casing', function() {
|
|
|
const a = [
|
|
|
'aaa',
|
|
|
'bbb',
|
|
|
'BBB',
|
|
|
'AAA',
|
|
|
]
|
|
|
a.sort(OC.Util.naturalSortCompare)
|
|
|
expect(a).toEqual([
|
|
|
'aaa',
|
|
|
'AAA',
|
|
|
'bbb',
|
|
|
'BBB',
|
|
|
])
|
|
|
})
|
|
|
it('sorts with numbers', function() {
|
|
|
const a = [
|
|
|
'124.txt',
|
|
|
'abc1',
|
|
|
'123.txt',
|
|
|
'abc',
|
|
|
'abc2',
|
|
|
'def (2).txt',
|
|
|
'ghi 10.txt',
|
|
|
'abc12',
|
|
|
'def.txt',
|
|
|
'def (1).txt',
|
|
|
'ghi 2.txt',
|
|
|
'def (10).txt',
|
|
|
'abc10',
|
|
|
'def (12).txt',
|
|
|
'z',
|
|
|
'ghi.txt',
|
|
|
'za',
|
|
|
'ghi 1.txt',
|
|
|
'ghi 12.txt',
|
|
|
'zz',
|
|
|
'15.txt',
|
|
|
'15b.txt',
|
|
|
]
|
|
|
a.sort(OC.Util.naturalSortCompare)
|
|
|
expect(a).toEqual([
|
|
|
'15.txt',
|
|
|
'15b.txt',
|
|
|
'123.txt',
|
|
|
'124.txt',
|
|
|
'abc',
|
|
|
'abc1',
|
|
|
'abc2',
|
|
|
'abc10',
|
|
|
'abc12',
|
|
|
'def.txt',
|
|
|
'def (1).txt',
|
|
|
'def (2).txt',
|
|
|
'def (10).txt',
|
|
|
'def (12).txt',
|
|
|
'ghi.txt',
|
|
|
'ghi 1.txt',
|
|
|
'ghi 2.txt',
|
|
|
'ghi 10.txt',
|
|
|
'ghi 12.txt',
|
|
|
'z',
|
|
|
'za',
|
|
|
'zz',
|
|
|
])
|
|
|
})
|
|
|
it('sorts with chinese characters', function() {
|
|
|
const a = [
|
|
|
'十.txt',
|
|
|
'一.txt',
|
|
|
'二.txt',
|
|
|
'十 2.txt',
|
|
|
'三.txt',
|
|
|
'四.txt',
|
|
|
'abc.txt',
|
|
|
'五.txt',
|
|
|
'七.txt',
|
|
|
'八.txt',
|
|
|
'九.txt',
|
|
|
'六.txt',
|
|
|
'十一.txt',
|
|
|
'波.txt',
|
|
|
'破.txt',
|
|
|
'莫.txt',
|
|
|
'啊.txt',
|
|
|
'123.txt',
|
|
|
]
|
|
|
a.sort(OC.Util.naturalSortCompare)
|
|
|
expect(a).toEqual([
|
|
|
'123.txt',
|
|
|
'abc.txt',
|
|
|
'一.txt',
|
|
|
'七.txt',
|
|
|
'三.txt',
|
|
|
'九.txt',
|
|
|
'二.txt',
|
|
|
'五.txt',
|
|
|
'八.txt',
|
|
|
'六.txt',
|
|
|
'十.txt',
|
|
|
'十 2.txt',
|
|
|
'十一.txt',
|
|
|
'啊.txt',
|
|
|
'四.txt',
|
|
|
'波.txt',
|
|
|
'破.txt',
|
|
|
'莫.txt',
|
|
|
])
|
|
|
})
|
|
|
cit('sorts with umlauts', function() {
|
|
|
const a = [
|
|
|
'öh.txt',
|
|
|
'Äh.txt',
|
|
|
'oh.txt',
|
|
|
'Üh 2.txt',
|
|
|
'Üh.txt',
|
|
|
'ah.txt',
|
|
|
'Öh.txt',
|
|
|
'uh.txt',
|
|
|
'üh.txt',
|
|
|
'äh.txt',
|
|
|
]
|
|
|
a.sort(OC.Util.naturalSortCompare)
|
|
|
expect(a).toEqual([
|
|
|
'ah.txt',
|
|
|
'äh.txt',
|
|
|
'Äh.txt',
|
|
|
'oh.txt',
|
|
|
'öh.txt',
|
|
|
'Öh.txt',
|
|
|
'uh.txt',
|
|
|
'üh.txt',
|
|
|
'Üh.txt',
|
|
|
'Üh 2.txt',
|
|
|
])
|
|
|
})
|
|
|
})
|
|
|
describe('Plugins', function() {
|
|
|
let plugin
|
|
|
|
|
|
beforeEach(function() {
|
|
|
plugin = {
|
|
|
name: 'Some name',
|
|
|
attach: function(obj) {
|
|
|
obj.attached = true
|
|
|
},
|
|
|
|
|
|
detach: function(obj) {
|
|
|
obj.attached = false
|
|
|
},
|
|
|
}
|
|
|
OC.Plugins.register('OC.Test.SomeName', plugin)
|
|
|
})
|
|
|
it('attach plugin to object', function() {
|
|
|
const obj = { something: true }
|
|
|
OC.Plugins.attach('OC.Test.SomeName', obj)
|
|
|
expect(obj.attached).toEqual(true)
|
|
|
OC.Plugins.detach('OC.Test.SomeName', obj)
|
|
|
expect(obj.attached).toEqual(false)
|
|
|
})
|
|
|
it('only call handler for target name', function() {
|
|
|
const obj = { something: true }
|
|
|
OC.Plugins.attach('OC.Test.SomeOtherName', obj)
|
|
|
expect(obj.attached).not.toBeDefined()
|
|
|
OC.Plugins.detach('OC.Test.SomeOtherName', obj)
|
|
|
expect(obj.attached).not.toBeDefined()
|
|
|
})
|
|
|
})
|
|
|
describe('Notifications', function() {
|
|
|
let showHtmlSpy
|
|
|
let 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.
|
|
|
*/
|
|
|
const getNotificationText = function($node) {
|
|
|
return $node.contents()[0].outerHTML
|
|
|
|| $node.contents()[0].nodeValue
|
|
|
}
|
|
|
|
|
|
beforeEach(function() {
|
|
|
clock = sinon.useFakeTimers()
|
|
|
})
|
|
|
afterEach(function() {
|
|
|
// jump past animations
|
|
|
clock.tick(10000)
|
|
|
clock.restore()
|
|
|
$('body .toastify').remove()
|
|
|
})
|
|
|
describe('showTemporary', function() {
|
|
|
it('shows a plain text notification with default timeout', function() {
|
|
|
OC.Notification.showTemporary('My notification test')
|
|
|
|
|
|
const $row = $('body .toastify')
|
|
|
expect($row.length).toEqual(1)
|
|
|
expect(getNotificationText($row)).toEqual('My notification test')
|
|
|
})
|
|
|
it('shows a HTML notification with default timeout', function() {
|
|
|
OC.Notification.showTemporary('<a>My notification test</a>', { isHTML: true })
|
|
|
|
|
|
const $row = $('body .toastify')
|
|
|
expect($row.length).toEqual(1)
|
|
|
expect(getNotificationText($row)).toEqual('<a>My notification test</a>')
|
|
|
})
|
|
|
it('hides itself after 7 seconds', function() {
|
|
|
OC.Notification.showTemporary('')
|
|
|
|
|
|
let $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 })
|
|
|
|
|
|
let $row = $('body .toastify')
|
|
|
expect($row.length).toEqual(1)
|
|
|
|
|
|
// travel in time +7000 milliseconds
|
|
|
clock.tick(7500)
|
|
|
|
|
|
$row = $('body .toastify')
|
|
|
expect($row.length).toEqual(1)
|
|
|
|
|
|
// 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: 10000 })
|
|
|
|
|
|
let $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('')
|
|
|
|
|
|
let $row = $('body .toastify')
|
|
|
expect($row.length).toEqual(1)
|
|
|
|
|
|
// travel in time +1000 seconds
|
|
|
clock.tick(1000000)
|
|
|
|
|
|
$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 })
|
|
|
|
|
|
let $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.showHtml('<p></p>')
|
|
|
|
|
|
let $row = $('body .toastify')
|
|
|
expect($row.length).toEqual(1)
|
|
|
|
|
|
// travel in time +1000 seconds
|
|
|
clock.tick(1000000)
|
|
|
|
|
|
$row = $('body .toastify')
|
|
|
expect($row.length).toEqual(1)
|
|
|
})
|
|
|
})
|
|
|
describe('hide', function() {
|
|
|
it('hides a temporary notification before its timeout expires', function() {
|
|
|
const hideCallback = sinon.spy()
|
|
|
|
|
|
const notification = OC.Notification.showTemporary('')
|
|
|
|
|
|
let $row = $('body .toastify')
|
|
|
expect($row.length).toEqual(1)
|
|
|
|
|
|
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 a notification before its timeout expires', function() {
|
|
|
const hideCallback = sinon.spy()
|
|
|
|
|
|
const notification = OC.Notification.show('', { timeout: 10000 })
|
|
|
|
|
|
let $row = $('body .toastify')
|
|
|
expect($row.length).toEqual(1)
|
|
|
|
|
|
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 a notification without timeout', function() {
|
|
|
const hideCallback = sinon.spy()
|
|
|
|
|
|
const notification = OC.Notification.show('')
|
|
|
|
|
|
let $row = $('body .toastify')
|
|
|
expect($row.length).toEqual(1)
|
|
|
|
|
|
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('cumulates several notifications', function() {
|
|
|
const $row1 = OC.Notification.showTemporary('One')
|
|
|
const $row2 = OC.Notification.showTemporary('Two', { timeout: 2000 })
|
|
|
const $row3 = OC.Notification.showTemporary('Three')
|
|
|
|
|
|
const $el = $('body')
|
|
|
let $rows = $el.find('.toastify')
|
|
|
expect($rows.length).toEqual(3)
|
|
|
|
|
|
expect($rows.eq(0).is($row3)).toEqual(true)
|
|
|
expect($rows.eq(1).is($row2)).toEqual(true)
|
|
|
expect($rows.eq(2).is($row1)).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() {
|
|
|
const $row1 = OC.Notification.show('One')
|
|
|
const $row2 = OC.Notification.show('Two')
|
|
|
|
|
|
const $el = $('body')
|
|
|
let $rows = $el.find('.toastify')
|
|
|
expect($rows.length).toEqual(2)
|
|
|
|
|
|
OC.Notification.hide($row2)
|
|
|
clock.tick(3000)
|
|
|
|
|
|
$rows = $el.find('.toastify')
|
|
|
expect($rows.length).toEqual(1)
|
|
|
expect($rows.eq(0).is($row1)).toEqual(true)
|
|
|
})
|
|
|
})
|
|
|
describe('global ajax errors', function() {
|
|
|
let reloadStub, ajaxErrorStub, clock
|
|
|
let notificationStub
|
|
|
const waitTimeMs = 6500
|
|
|
let 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('does not reload the page if the user was navigating away', function() {
|
|
|
const xhr = { status: 0 }
|
|
|
OC._userIsNavigatingAway = true
|
|
|
clock.tick(100)
|
|
|
|
|
|
$(document).trigger(new $.Event('ajaxError'), xhr)
|
|
|
|
|
|
clock.tick(waitTimeMs)
|
|
|
expect(reloadStub.notCalled).toEqual(true)
|
|
|
})
|
|
|
|
|
|
it('shows a temporary notification if the connection is lost', function() {
|
|
|
const xhr = { status: 0 }
|
|
|
spyOn(OC, '_ajaxConnectionLostHandler')
|
|
|
|
|
|
$(document).trigger(new $.Event('ajaxError'), xhr)
|
|
|
clock.tick(101)
|
|
|
|
|
|
expect(OC._ajaxConnectionLostHandler.calls.count()).toBe(1)
|
|
|
})
|
|
|
})
|
|
|
describe('Snapper', function() {
|
|
|
let snapConstructorStub
|
|
|
let snapperStub
|
|
|
let 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('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()
|
|
|
|
|
|
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(snapperStub.enable.calledOnce).toBe(true)
|
|
|
expect(snapperStub.disable.calledOnce).toBe(true)
|
|
|
})
|
|
|
it('is not enabled when resizing to a narrow screen after disallowing the gesture', 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)
|
|
|
})
|
|
|
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)
|
|
|
})
|
|
|
})
|
|
|
})
|