diff --git a/test/v2/tests.ts/lockUnlock/.createFiles.ts b/test/v2/tests.ts/lockUnlock/.createFiles.ts new file mode 100644 index 00000000..30ee4869 --- /dev/null +++ b/test/v2/tests.ts/lockUnlock/.createFiles.ts @@ -0,0 +1,146 @@ +import { TestCallback, TestInfo } from '../Type' +import { v2 } from '../../../../lib/index.js' + +export interface Lock +{ + scope : string + type : string + depth : number + owner : string | v2.XMLElement | v2.XMLElement[] + timeoutSec : number + uuid : string + root : string +} + +export function lockResource( + server : v2.WebDAVServer, + info : TestInfo, + isValid : TestCallback, + pathNameToLock : string, + depth : number, + isExclusive : boolean, + callback : (lock : Lock) => void) : void +export function lockResource( + server : v2.WebDAVServer, + info : TestInfo, + isValid : TestCallback, + pathNameToLock : string, + depth : number, + isExclusive : boolean, + expectedResponseCode : number, + callback : (lock : Lock) => void) : void +export function lockResource( + server : v2.WebDAVServer, + info : TestInfo, + isValid : TestCallback, + pathNameToLock : string, + depth : number, + isExclusive : boolean, + _expectedResponseCode : number | ((lock : Lock) => void), + _callback ?: (lock : Lock) => void) : void +{ + const expectedResponseCode = _callback ? _expectedResponseCode as number : v2.HTTPCodes.OK; + const callback = _callback ? _callback : _expectedResponseCode as (lock : Lock) => void; + + info.reqXML({ + url: 'http://localhost:' + server.options.port + '/' + pathNameToLock, + method: 'LOCK', + headers: { + depth: depth === -1 ? 'Infinity' : depth.toString() + }, + body: 'http://example.org/~ejw/contact.html' + }, expectedResponseCode, (res, xml) => { + if(expectedResponseCode !== v2.HTTPCodes.Created && expectedResponseCode !== v2.HTTPCodes.OK) + return callback(null); + + try + { + const activeLock = xml.find('DAV:prop').find('DAV:lockdiscovery').find('DAV:activelock'); + const sDepth = activeLock.find('DAV:depth').findText().trim().toLowerCase(); + const sTimeout = activeLock.find('DAV:timeout').findText(); + + const lock = { + scope: activeLock.find('DAV:lockscope').elements[0].name.replace('DAV:', '').toLowerCase(), + type: activeLock.find('DAV:locktype').elements[0].name.replace('DAV:', '').toLowerCase(), + depth: sDepth === 'infinity' ? -1 : parseInt(sDepth), + owner: activeLock.find('DAV:owner').elements, + timeoutSec: parseInt(sTimeout.substring(sTimeout.indexOf(':') + 1)), + uuid: activeLock.find('DAV:locktoken').find('DAV:href').findText(), + root: activeLock.find('DAV:lockroot').find('DAV:href').findText() + }; + + if(lock.type !== 'write') + return isValid(false, 'The lock type must be write when requested to be write.', lock.type); + if(isExclusive && lock.scope !== 'exclusive') + return isValid(false, 'The lock scope must be exclusive when requested to be exclusive.', lock.scope); + if(!isExclusive && lock.scope !== 'shared') + return isValid(false, 'The lock scope must be shared when requested to be shared.', lock.scope); + + try + { + if(lock.owner[0].findText() !== 'http://example.org/~ejw/contact.html') + return isValid(false, 'The value of the owner is not perfectly saved.'); + } + catch(ex) + { + return isValid(false, 'The owner property is not valid.', ex); + } + + callback(lock); + } + catch(ex) + { + return isValid(false, 'The WebDAV XML response is not valid.', ex); + } + }) +} + +export function starter( + server : v2.WebDAVServer, + info : TestInfo, + isValid : TestCallback, + pathNameToLock : string, + depth : number, + isExclusive : boolean, + callback : (lock : Lock) => void) : void +export function starter( + server : v2.WebDAVServer, + info : TestInfo, + isValid : TestCallback, + pathNameToLock : string, + depth : number, + isExclusive : boolean, + expectedResponseCode : number, + callback : (lock : Lock) => void) : void +export function starter( + server : v2.WebDAVServer, + info : TestInfo, + isValid : TestCallback, + pathNameToLock : string, + depth : number, + isExclusive : boolean, + _expectedResponseCode : number | ((lock : Lock) => void), + _callback ?: (lock : Lock) => void) : void +{ + const expectedResponseCode = _callback ? _expectedResponseCode as number : v2.HTTPCodes.OK; + const callback = _callback ? _callback : _expectedResponseCode as (lock : Lock) => void; + + server.rootFileSystem.addSubTree(info.ctx, { + 'folder': { + 'folder2': { + 'folder3': { + 'folder4': { + 'file': v2.ResourceType.File + } + } + } + }, + 'file': v2.ResourceType.File, + 'hybrid': v2.ResourceType.Hybrid, + 'noResource': v2.ResourceType.NoResource, + }, (e) => { + if(e) return isValid(false, 'Cannot call "addSubTree(...)".', e); + + lockResource(server, info, isValid, pathNameToLock, depth, isExclusive, expectedResponseCode, callback); + }) +} diff --git a/test/v2/tests.ts/lockUnlock/lockOnDirectory.ts b/test/v2/tests.ts/lockUnlock/lockOnDirectory.ts new file mode 100644 index 00000000..2c6833a3 --- /dev/null +++ b/test/v2/tests.ts/lockUnlock/lockOnDirectory.ts @@ -0,0 +1,43 @@ +import { Test } from '../Type' +import { v2 } from '../../../../lib/index.js' +import { starter, lockResource } from './.createFiles' + +export default ((info, isValid) => +{ + const server1 = info.init(5); + + starter(server1, info, isValid, 'folder', 0, true, (lock) => { + lockResource(server1, info, isValid, 'folder', 0, true, v2.HTTPCodes.Locked, (lock) => { + isValid(true); + }) + }) + + const server2 = info.startServer(); + starter(server2, info, isValid, 'folder', -1, true, (lock) => { + lockResource(server2, info, isValid, 'folder/folder2/folder3/folder4/file', 0, true, v2.HTTPCodes.Locked, (lock) => { + isValid(true); + }) + }) + + const server3 = info.startServer(); + starter(server3, info, isValid, 'folder', 2, true, (lock) => { + lockResource(server3, info, isValid, 'folder/folder2/folder3/folder4/file', 0, true, (lock) => { + isValid(true); + }) + }) + + const server4 = info.startServer(); + starter(server4, info, isValid, 'folder', 2, true, (lock) => { + lockResource(server4, info, isValid, 'folder/folder2/folder3/folder4/fileX', 0, true, v2.HTTPCodes.Created, (lock) => { + isValid(true); + }) + }) + + const server5 = info.startServer(); + starter(server5, info, isValid, 'folder', -1, true, (lock) => { + lockResource(server5, info, isValid, 'folder/folder2/folder3/folder4/fileX', 0, true, v2.HTTPCodes.Locked, (lock) => { + isValid(true); + }) + }) + +}) as Test; diff --git a/test/v2/tests.ts/lockUnlock/lockOnFile.ts b/test/v2/tests.ts/lockUnlock/lockOnFile.ts new file mode 100644 index 00000000..134216cc --- /dev/null +++ b/test/v2/tests.ts/lockUnlock/lockOnFile.ts @@ -0,0 +1,22 @@ +import { Test } from '../Type' +import { v2 } from '../../../../lib/index.js' +import { starter, lockResource } from './.createFiles' + +export default ((info, isValid) => +{ + const server1 = info.init(2); + + starter(server1, info, isValid, 'file', 0, true, (lock) => { + lockResource(server1, info, isValid, 'file', 0, true, v2.HTTPCodes.Locked, (lock) => { + isValid(true); + }) + }) + + const server2 = info.startServer(); + starter(server2, info, isValid, 'file', -1, true, (lock) => { + lockResource(server2, info, isValid, 'file', -1, true, v2.HTTPCodes.Locked, (lock) => { + isValid(true); + }) + }) + +}) as Test; diff --git a/test/v2/tests.ts/lockUnlock/lockOnHybrid.ts b/test/v2/tests.ts/lockUnlock/lockOnHybrid.ts new file mode 100644 index 00000000..178f7488 --- /dev/null +++ b/test/v2/tests.ts/lockUnlock/lockOnHybrid.ts @@ -0,0 +1,15 @@ +import { Test } from '../Type' +import { v2 } from '../../../../lib/index.js' +import { starter, lockResource } from './.createFiles' + +export default ((info, isValid) => +{ + const server = info.init(1); + + starter(server, info, isValid, 'hybrid', 0, true, (lock) => { + lockResource(server, info, isValid, 'hybrid', 0, true, v2.HTTPCodes.Locked, (lock) => { + isValid(true); + }) + }) + +}) as Test; diff --git a/test/v2/tests.ts/lockUnlock/lockOnNoResourceType.ts b/test/v2/tests.ts/lockUnlock/lockOnNoResourceType.ts new file mode 100644 index 00000000..f2913799 --- /dev/null +++ b/test/v2/tests.ts/lockUnlock/lockOnNoResourceType.ts @@ -0,0 +1,15 @@ +import { Test } from '../Type' +import { v2 } from '../../../../lib/index.js' +import { starter, lockResource } from './.createFiles' + +export default ((info, isValid) => +{ + const server = info.init(1); + + starter(server, info, isValid, 'noResource', 0, true, (lock) => { + lockResource(server, info, isValid, 'noResource', 0, true, v2.HTTPCodes.Locked, (lock) => { + isValid(true); + }) + }) + +}) as Test; diff --git a/test/v2/tests.ts/lockUnlock/lockOnUndefined.ts b/test/v2/tests.ts/lockUnlock/lockOnUndefined.ts new file mode 100644 index 00000000..06da6fcb --- /dev/null +++ b/test/v2/tests.ts/lockUnlock/lockOnUndefined.ts @@ -0,0 +1,23 @@ +import { Test } from '../Type' +import { v2 } from '../../../../lib/index.js' +import { starter, lockResource } from './.createFiles' + +export default ((info, isValid) => +{ + const server = info.init(3); + + starter(server, info, isValid, 'fileUndefined', 0, true, v2.HTTPCodes.Created, (lock) => { + lockResource(server, info, isValid, 'fileUndefined', 0, true, v2.HTTPCodes.Locked, (lock) => { + isValid(true); + }) + }) + + starter(info.startServer(), info, isValid, 'folderUndefined/fileUndefined', 0, true, v2.HTTPCodes.Conflict, (lock) => { + isValid(true); + }) + + starter(info.startServer(), info, isValid, 'file/subFile', 0, true, v2.HTTPCodes.Conflict, (lock) => { + isValid(true); + }) + +}) as Test;