test: removed mocha

Massimo Melina committed Apr 16, 2025 at 23:31 UTC 02b240e1f4e522fa1fd27435bf4e418f49c8715b
2 files changed +117 -120
package.json
+6 -7
@@ -8,7 +8,7 @@
8 "author": "Massimo Melina <a@rejetto.com>",
9 "workspaces": [ "admin", "frontend", "shared", "mui-grid-form" ],
10 "scripts": {
11 - "watch-server": "cross-env DEV=1 nodemon --ignore tests/ --watch src -e ts,tsx --exec ts-node src",
11 + "watch-server": "cross-env DEV=1 nodemon --ignore tests/ --watch src -e ts,tsx --exec tsx src",
12 "watch-server-proxied": "cross-env FRONTEND_PROXY=3005 ADMIN_PROXY=3006 npm run watch-server",
13 "start-frontend": "npm run start --workspace=frontend",
14 "start-admin": "npm run start --workspace=admin",
@@ -17,9 +17,9 @@
17 "build-frontend": "npm run build --workspace=frontend",
18 "build-admin": "npm run build --workspace=admin",
19 "server-for-test": "node dist/src --cwd . --config tests --debug && rm custom.html",
20 - "server-for-test-dev": "cross-env DEV=1 FRONTEND_PROXY=3005 ADMIN_PROXY=3006 nodemon --ignore tests/ --watch src -e ts,tsx --exec ts-node src -- --cwd . --config tests",
21 - "test": "mocha -r ts-node/register 'tests/**/*.ts'",
22 - "test-with-server": "node dist/src --cwd . --config tests & pid=$! && sleep 2 && mocha -r ts-node/register 'tests/**/*.ts'; mocha_exit=$?; kill $pid; exit $mocha_exit",
20 + "server-for-test-dev": "cross-env DEV=1 FRONTEND_PROXY=3005 ADMIN_PROXY=3006 nodemon --ignore tests/ --watch src -e ts,tsx --exec tsx src -- --cwd . --config tests",
21 + "test": "node --import tsx --test tests/test.ts",
22 + "test-with-server": "node dist/src --cwd . --config tests & pid=$! && sleep 2 && node --import tsx --test tests/test.ts; _exit=$?; kill $pid; exit $_exit",
23 "test-ui": "npx playwright test --ui",
24 "pub": "cd dist && npm publish",
25 "dist": "npm run build-all && npx playwright test && npm run dist-bin",
@@ -112,7 +112,6 @@
112 "@types/lodash": "^4.14.178",
113 "@types/mime-types": "^2.1.1",
114 "@types/minimist": "^1.2.2",
115 - "@types/mocha": "^10.0.10",
115 "@types/node": "^20.17.30",
116 "@types/node-forge": "^1.3.11",
117 "@types/picomatch": "^2.3.3",
@@ -121,10 +120,10 @@
120 "@yao-pkg/pkg": "^6.4.0",
121 "cross-env": "^7.0.3",
122 "koa-better-http-proxy": "^0.2.9",
124 - "mocha": "^10.8.2",
123 "nm-prune": "^5.0.0",
124 "nodemon": "^3.1.9",
125 "tough-cookie": "^4.0.0",
128 - "ts-node": "^10.4.0"
126 + "tsx": "^4.19.3",
127 + "typescript": "4.9.5"
128 }
129 }
tests/test.ts
+111 -113
@@ -1,3 +1,5 @@
1 +import test, { describe, before, after } from 'node:test';
2 +import { promisify } from 'util'
3 import { srpClientSequence } from '../src/srp'
4 import { createReadStream, statSync } from 'fs'
5 import { basename, dirname, resolve } from 'path'
@@ -45,159 +47,155 @@ function makeReadableThatTakes(ms: number) {
47
48 describe('basics', () => {
49 //before(async () => appStarted)
48 - it('frontend', req('/', /<body>/, { headers: { accept: '*/*' } })) // workaround: 'accept' is necessary when running server-for-test-dev, still don't know why
49 - it('force slash', req('/f1', 302, { noRedirect: true }))
50 - it('list', reqList('/f1/', { inList:['f2/', 'page/'] }))
51 - it('search', reqList('f1', { inList:['f2/'], outList:['page'] }, { search:'2' }))
52 - it('search root', reqList('/', { inList:['cantListPage/'], outList:['cantListPage/page/'] }, { search:'page' }))
53 - it('download.mime', req('/f1/f2/alfa.txt', { re:/abcd/, mime:'text/plain' }))
54 - it('download.partial', req('/f1/f2/alfa.txt', /a[^d]+$/, { // only "abc" is expected
50 + test('frontend', req('/', /<body>/, { headers: { accept: '*/*' } })) // workaround: 'accept' is necessary when running server-for-test-dev, still don't know why
51 + test('force slash', req('/f1', 302, { noRedirect: true }))
52 + test('list', reqList('/f1/', { inList:['f2/', 'page/'] }))
53 + test('search', reqList('f1', { inList:['f2/'], outList:['page'] }, { search:'2' }))
54 + test('search root', reqList('/', { inList:['cantListPage/'], outList:['cantListPage/page/'] }, { search:'page' }))
55 + test('download.mime', req('/f1/f2/alfa.txt', { re:/abcd/, mime:'text/plain' }))
56 + test('download.partial', req('/f1/f2/alfa.txt', /a[^d]+$/, { // only "abc" is expected
57 headers: { Range: 'bytes=0-2' }
58 }))
57 - it('bad range', req('/f1/f2/alfa.txt', 416, {
59 + test('bad range', req('/f1/f2/alfa.txt', 416, {
60 headers: { Range: 'bytes=7-' }
61 }))
60 - it('roots', req('/f2/alfa.txt', 200, { baseUrl: BASE_URL.replace('localhost', '127.0.0.1') })) // host 127.0.0.1 is rooted in /f1
61 - it('website', req('/f1/page/', { re:/This is a test/, mime:'text/html' }))
62 - it('traversal', req('/f1/page/.%2e/.%2e/README.md', 418))
63 - it('custom mime from above', req('/tests/page/index.html', { status: 200, mime:'text/plain' }))
64 - it('name encoding', req('/x%25%23x', 200))
62 + test('roots', req('/f2/alfa.txt', 200, { baseUrl: BASE_URL.replace('localhost', '127.0.0.1') })) // host 127.0.0.1 is rooted in /f1
63 + test('website', req('/f1/page/', { re:/This is a test/, mime:'text/html' }))
64 + test('traversal', req('/f1/page/.%2e/.%2e/README.md', 418))
65 + test('custom mime from above', req('/tests/page/index.html', { status: 200, mime:'text/plain' }))
66 + test('name encoding', req('/x%25%23x', 200))
67
66 - it('missing perm', reqList('/for-admins/', 401))
67 - it('missing perm.file', req('/for-admins/alfa.txt', 401))
68 + test('missing perm', reqList('/for-admins/', 401))
69 + test('missing perm.file', req('/for-admins/alfa.txt', 401))
70
69 - it('forbidden list', req('/cantListPage/page/', 403))
70 - it('forbidden list.api', reqList('/cantListPage/page/', 403))
71 - it('forbidden list.cant see', reqList('/cantListPage/', { outList:['page/'] }))
72 - it('forbidden list.but readable file', req('/cantListPage/page/gpl.png', 200))
73 - it('forbidden list.alternative method', reqList('/cantListPageAlt/page/', 403))
74 - it('forbidden list.match **', req('/cantListPageAlt/page/gpl.png', 401))
71 + test('forbidden list', req('/cantListPage/page/', 403))
72 + test('forbidden list.api', reqList('/cantListPage/page/', 403))
73 + test('forbidden list.cant see', reqList('/cantListPage/', { outList:['page/'] }))
74 + test('forbidden list.but readable file', req('/cantListPage/page/gpl.png', 200))
75 + test('forbidden list.alternative method', reqList('/cantListPageAlt/page/', 403))
76 + test('forbidden list.match **', req('/cantListPageAlt/page/gpl.png', 401))
77
76 - it('cantListBut', reqList('/cantListBut/', 403))
77 - it('cantListBut.zip', req('/cantListBut/?get=zip', 403))
78 - it('cantListBut.parent', reqList('/', { permInList: { 'cantListBut/': 'l' } }))
79 - it('cantListBut.child masked', reqList('/cantListBut/page', 200))
80 - it('cantSearchForMasks', reqList('/', { outList: ['cantSearchForMasks/page/gpl.png'] }, { search: 'gpl' }))
81 - it('cantReadBut', reqList('/cantReadBut/', 403))
82 - it('cantReadBut.can', req('/cantReadBut/alfa.txt', 200))
83 - it('cantReadBut.parent', reqList('/', { permInList: { 'cantReadBut/': '!r' } }))
84 - it('cantReadButChild', req('/cantReadButChild/alfa.txt', 401))
85 - it('cantReadButChild.parent', reqList('/', { permInList: { 'cantReadButChild/': 'R' } }))
78 + test('cantListBut', reqList('/cantListBut/', 403))
79 + test('cantListBut.zip', req('/cantListBut/?get=zip', 403))
80 + test('cantListBut.parent', reqList('/', { permInList: { 'cantListBut/': 'l' } }))
81 + test('cantListBut.child masked', reqList('/cantListBut/page', 200))
82 + test('cantSearchForMasks', reqList('/', { outList: ['cantSearchForMasks/page/gpl.png'] }, { search: 'gpl' }))
83 + test('cantReadBut', reqList('/cantReadBut/', 403))
84 + test('cantReadBut.can', req('/cantReadBut/alfa.txt', 200))
85 + test('cantReadBut.parent', reqList('/', { permInList: { 'cantReadBut/': '!r' } }))
86 + test('cantReadButChild', req('/cantReadButChild/alfa.txt', 401))
87 + test('cantReadButChild.parent', reqList('/', { permInList: { 'cantReadButChild/': 'R' } }))
88
87 - it('cantReadPage', reqList('/cantReadPage/page', 403))
88 - it('cantReadPage.zip', req('/cantReadPage/page/?get=zip', 403, { method:'HEAD' }))
89 - it('cantReadPage.file', req('/cantReadPage/page/gpl.png', 403))
90 - it('cantReadPage.parent', reqList('/cantReadPage', { permInList: { 'page/': 'lr' } }))
91 - it('cantReadRealFolder', reqList('/cantReadRealFolder', 403))
92 - it('cantReadRealFolder.file', req('/cantReadRealFolder/page/gpl.png', 403))
89 + test('cantReadPage', reqList('/cantReadPage/page', 403))
90 + test('cantReadPage.zip', req('/cantReadPage/page/?get=zip', 403, { method:'HEAD' }))
91 + test('cantReadPage.file', req('/cantReadPage/page/gpl.png', 403))
92 + test('cantReadPage.parent', reqList('/cantReadPage', { permInList: { 'page/': 'lr' } }))
93 + test('cantReadRealFolder', reqList('/cantReadRealFolder', 403))
94 + test('cantReadRealFolder.file', req('/cantReadRealFolder/page/gpl.png', 403))
95
94 - it('renameChild', reqList('/renameChild/tests', { inList:['renamed1'] }))
95 - it('renameChild.get', req('/renameChild/tests/renamed1', /abc/))
96 - it('renameChild.deeper', reqList('/renameChild/tests/page', { inList:['renamed2'] }))
97 - it('renameChild.get deeper', req('/renameChild/tests/page/renamed2', /PNG/))
96 + test('renameChild', reqList('/renameChild/tests', { inList:['renamed1'] }))
97 + test('renameChild.get', req('/renameChild/tests/renamed1', /abc/))
98 + test('renameChild.deeper', reqList('/renameChild/tests/page', { inList:['renamed2'] }))
99 + test('renameChild.get deeper', req('/renameChild/tests/page/renamed2', /PNG/))
100
99 - it('cantSeeThis', reqList('/', { outList:['cantSeeThis/'] }))
100 - it('cantSeeThis.children', reqList('/cantSeeThis', { outList:['hi/'] }))
101 - it('cantSeeThisButChildren', reqList('/', { outList:['cantSeeThisButChildren/'] }))
102 - it('cantSeeThisButChildren.children', reqList('/cantSeeThisButChildren', { inList:['hi/'] }))
103 - it('cantZipFolder', req('/cantSeeThisButChildren/?get=zip', 403))
104 - it('cantZipFolder.butChildren', req('/cantSeeThisButChildren/hi/?get=zip', 200))
105 - it('cantSeeThisButChildrenMasks', reqList('/', { outList:['cantSeeThisButChildrenMasks/'] }))
106 - it('cantSeeThisButChildrenMasks.children', reqList('/cantSeeThisButChildrenMasks', { inList:['hi/'] }))
101 + test('cantSeeThis', reqList('/', { outList:['cantSeeThis/'] }))
102 + test('cantSeeThis.children', reqList('/cantSeeThis', { outList:['hi/'] }))
103 + test('cantSeeThisButChildren', reqList('/', { outList:['cantSeeThisButChildren/'] }))
104 + test('cantSeeThisButChildren.children', reqList('/cantSeeThisButChildren', { inList:['hi/'] }))
105 + test('cantZipFolder', req('/cantSeeThisButChildren/?get=zip', 403))
106 + test('cantZipFolder.butChildren', req('/cantSeeThisButChildren/hi/?get=zip', 200))
107 + test('cantSeeThisButChildrenMasks', reqList('/', { outList:['cantSeeThisButChildrenMasks/'] }))
108 + test('cantSeeThisButChildrenMasks.children', reqList('/cantSeeThisButChildrenMasks', { inList:['hi/'] }))
109
108 - it('masks.only', reqList('/cantSeeThisButChildren/hi', { inList:['page/'] }))
109 - it('masks.only.fromDisk', reqList('/cantSeeThisButChildren/hi/page', 403))
110 - it('masks.only.fromDisk.file', req('/cantSeeThisButChildren/hi/page/gpl.png', 403))
110 + test('masks.only', reqList('/cantSeeThisButChildren/hi', { inList:['page/'] }))
111 + test('masks.only.fromDisk', reqList('/cantSeeThisButChildren/hi/page', 403))
112 + test('masks.only.fromDisk.file', req('/cantSeeThisButChildren/hi/page/gpl.png', 403))
113
112 - it('protectFromAbove', req('/protectFromAbove/child/alfa.txt', 403))
113 - it('protectFromAbove.list', reqList('/protectFromAbove/child/', { inList:['alfa.txt'] }))
114 - it('inheritNegativeMask', reqList('/tests/page', { outList: ['index.html'] }))
114 + test('protectFromAbove', req('/protectFromAbove/child/alfa.txt', 403))
115 + test('protectFromAbove.list', reqList('/protectFromAbove/child/', { inList:['alfa.txt'] }))
116 + test('inheritNegativeMask', reqList('/tests/page', { outList: ['index.html'] }))
117
118 const zipSize = 13010
119 const zipOfs = 0x1359
118 - it('zip.head', req('/f1/?get=zip', { empty:true, length:zipSize }, { method:'HEAD' }) )
119 - it('zip.partial', req('/f1/?get=zip', { re:/^C3$/, length: 2 }, { headers: { Range: `bytes=${zipOfs}-${zipOfs+1}` } }) )
120 - it('zip.partial.resume', req('/f1/?get=zip', { re:/^C3/, length:zipSize-zipOfs }, { headers: { Range: `bytes=${zipOfs}-` } }) )
121 - it('zip.partial.end', req('/f1/f2/?get=zip', { re:/^6/, length:10 }, { headers: { Range: 'bytes=-10' } }) )
122 - it('zip.alfa is forbidden', req('/protectFromAbove/child/?get=zip&list=alfa.txt//renamed', { empty: true, length:118 }, { method:'HEAD' }))
123 - it('zip.cantReadPage', req('/cantReadPage/?get=zip', { length: 4800 }, { method:'HEAD' }))
120 + test('zip.head', req('/f1/?get=zip', { empty:true, length:zipSize }, { method:'HEAD' }) )
121 + test('zip.partial', req('/f1/?get=zip', { re:/^C3$/, length: 2 }, { headers: { Range: `bytes=${zipOfs}-${zipOfs+1}` } }) )
122 + test('zip.partial.resume', req('/f1/?get=zip', { re:/^C3/, length:zipSize-zipOfs }, { headers: { Range: `bytes=${zipOfs}-` } }) )
123 + test('zip.partial.end', req('/f1/f2/?get=zip', { re:/^6/, length:10 }, { headers: { Range: 'bytes=-10' } }) )
124 + test('zip.alfa is forbidden', req('/protectFromAbove/child/?get=zip&list=alfa.txt//renamed', { empty: true, length:118 }, { method:'HEAD' }))
125 + test('zip.cantReadPage', req('/cantReadPage/?get=zip', { length: 4800 }, { method:'HEAD' }))
126
125 - it('referer', req('/f1/page/gpl.png', 403, {
127 + test('referer', req('/f1/page/gpl.png', 403, {
128 headers: { Referer: 'https://some-website.com/try-to-trick/x.com/' }
129 }))
130
129 - it('upload.need account', reqUpload( UPLOAD_DEST, 401))
130 - it('upload.post', done => { // this is also testing basic-auth
131 - const cmd = `curl -u ${username}:${password} -F upload=@${SAMPLE_FILE_PATH} ${BASE_URL}${UPLOAD_ROOT}`;
132 - exec(cmd, (err, out) => {
133 - if (err) return done(err)
134 - const fn = resolve(__dirname, basename(decodeURI(tryJson(out)?.uris?.[0])))
135 - if (!fn) return done("unexpected output " + out)
136 - try {
137 - const stats = statSync(fn)
138 - rm(fn).catch(() => {}) // clear
139 - done(stats?.size !== statSync(SAMPLE_FILE_PATH).size && "unexpected size for " + fn)
140 - }
141 - catch (e) { done(e) }
142 - })
143 - })
144 - it('create_folder', reqApi('create_folder', { uri: UPLOAD_ROOT, name: 'temp' }, 401))
145 - it('delete.no perm', req('/for-admins/', 405, { method: 'delete' }))
146 - it('delete.need account', req(UPLOAD_ROOT, 401, { method: 'delete'}))
147 - it('rename.no perm', reqApi('rename', { uri: '/for-admins', dest: 'any' }, 401))
148 - it('of_disabled.cantLogin', () => login('of_disabled').then(() => { throw Error('logged in') }, () => 0))
149 - it('allow_net.canLogin', () => login('rejetto')) // localhost is normally resolved as ::1
150 - it('allow_net.cantLogin', () => {
131 + test('upload.need account', reqUpload( UPLOAD_DEST, 401))
132 + test('upload.post', () => // this is also testing basic-auth
133 + promisify(exec)(`curl -u ${username}:${password} -F upload=@${SAMPLE_FILE_PATH} ${BASE_URL}${UPLOAD_ROOT}`).then(x => {
134 + const fn = resolve(__dirname, basename(decodeURI(tryJson(x.stdout)?.uris?.[0])))
135 + if (!fn) throw "unexpected output " + (x.stdout || x.stderr)
136 + const stats = statSync(fn)
137 + rm(fn).catch(() => {}) // clear
138 + if (stats?.size !== statSync(SAMPLE_FILE_PATH).size)
139 + throw "unexpected size for " + fn
140 + }))
141 + test('create_folder', reqApi('create_folder', { uri: UPLOAD_ROOT, name: 'temp' }, 401))
142 + test('delete.no perm', req('/for-admins/', 405, { method: 'delete' }))
143 + test('delete.need account', req(UPLOAD_ROOT, 401, { method: 'delete'}))
144 + test('rename.no perm', reqApi('rename', { uri: '/for-admins', dest: 'any' }, 401))
145 + test('of_disabled.cantLogin', () => login('of_disabled').then(() => { throw Error('logged in') }, () => {}))
146 + test('allow_net.canLogin', () => login('rejetto')) // localhost is normally resolved as ::1
147 + test('allow_net.cantLogin', () => {
148 defaultBaseUrl = BASE_URL.replace('localhost', '127.0.0.1')
152 - return login('rejetto').then(() => { throw Error('logged in') }, () => 0)
149 + return login('rejetto').then(() => { throw Error('logged in') }, () => {})
150 .finally(() => defaultBaseUrl = BASE_URL)
151 })
152
156 - it('folder size', reqApi('get_folder_size', { uri: 'f1/page' }, res => res.bytes === 6328 ))
157 - it('folder size.cant', reqApi('get_folder_size', { uri: 'for-admins' }, 401))
153 + test('folder size', reqApi('get_folder_size', { uri: 'f1/page' }, res => res.bytes === 6328 ))
154 + test('folder size.cant', reqApi('get_folder_size', { uri: 'for-admins' }, 401))
155
159 - it('get_accounts', reqApi('get_accounts', {}, 401)) // admin api requires login
160 - it('url login', done =>
161 - exec(`curl -v "${BASE_URL}/for-admins/?login=${username}:${password}"`, (err, out) =>
162 - done(err || (out?.includes('Redirect') ? null : "failed")) ) )
156 + test('get_accounts', reqApi('get_accounts', {}, 401)) // admin api requires login
157 + test('url login', () => promisify(exec)(`curl -v "${BASE_URL}/for-admins/?login=${username}:${password}"`).then(x => {
158 + if (!x.stdout?.includes('Redirect'))
159 + throw x.stderr || "failed"
160 + }))
161 })
162
163 // do this before login, or max_dl_accounts config will override max_dl
164 describe('limits', () => {
165 const fn = ROOT + 'big'
166 before(() => writeFile(fn, BIG_CONTENT))
169 - it('max_dl', () => testMaxDl('/' + fn, 1, 2))
167 + test('max_dl', () => testMaxDl('/' + fn, 1, 2))
168 after(() => rm(fn))
169 })
170
171 describe('accounts', () => {
172 before(() => login(username))
175 - it('get_accounts', reqApi('get_accounts', {}, ({ list }) => _.find(list, { username }) && _.find(list, { username: 'admins' })))
173 + test('get_accounts', reqApi('get_accounts', {}, ({ list }) => _.find(list, { username }) && _.find(list, { username: 'admins' })))
174 const add = 'test-Add'
177 - it('accounts.add', reqApi('add_account', { username: add, overwrite: true }, res => res?.username === add.toLowerCase()))
178 - it('accounts.remove', reqApi('del_account', { username: add }, 200))
175 + test('accounts.add', reqApi('add_account', { username: add, overwrite: true }, res => res?.username === add.toLowerCase()))
176 + test('accounts.remove', reqApi('del_account', { username: add }, 200))
177 })
178
179 describe('after-login', () => {
180 before(() => login(username))
183 - it('create_folder', reqApi('create_folder', { uri: UPLOAD_ROOT, name: 'temp' }, 200))
184 - it('inherit.perm', reqList('/for-admins/', { inList:['alfa.txt'] }))
185 - it('inherit.disabled', reqList('/for-disabled/', 401))
186 - it('upload.never', reqUpload('/random', 403))
187 - it('upload.ok', reqUpload(UPLOAD_DEST, 200))
188 - it('upload.crossing', reqUpload(UPLOAD_DEST.replace('temp', '../..'), 418))
189 - it('upload.overlap', async () => {
181 + test('create_folder', reqApi('create_folder', { uri: UPLOAD_ROOT, name: 'temp' }, 200))
182 + test('inherit.perm', reqList('/for-admins/', { inList:['alfa.txt'] }))
183 + test('inherit.disabled', reqList('/for-disabled/', 401))
184 + test('upload.never', reqUpload('/random', 403))
185 + test('upload.ok', reqUpload(UPLOAD_DEST, 200))
186 + test('upload.crossing', reqUpload(UPLOAD_DEST.replace('temp', '../..'), 418))
187 + test('upload.overlap', async () => {
188 const ms = 300
189 const first = reqUpload(UPLOAD_DEST, 200, makeReadableThatTakes(ms))()
190 await wait(ms/3)
191 await reqUpload(UPLOAD_DEST, 409)() // should conflict
192 await first
193 })
196 - it('upload.concurrent', () => Promise.all([
194 + test('upload.concurrent', { timeout: 5000 }, () => Promise.all([
195 reqUpload(UPLOAD_DEST, 200, new StringRepeaterStream(BIG_CONTENT, 150))(), // 300MB
196 ..._.range(3).map(i => reqUpload(UPLOAD_DEST + i, 200, new StringRepeaterStream(BIG_CONTENT, 50))()) // 3 x 100MB
199 - ])).timeout(5000)
200 - it('upload.interrupted', async () => {
197 + ]).then(() => {}))
198 + test('upload.interrupted', async () => {
199 const fn = resolve(__dirname, UPLOAD_RELATIVE.replace('/', '/hfs$upload-'))
200 await rm(fn, {force: true})
201 const neededTime = 300
@@ -229,14 +227,14 @@ describe('after-login', () => {
227 await reqUpload(UPLOAD_DEST, 200, Readable.from(BIG_CONTENT.slice(partial)), BIG_CONTENT.length, partial)()
228 })
229 const renameTo = 'z'
232 - it('rename.ok', reqApi('rename', { uri: UPLOAD_DEST, dest: renameTo }, 200))
233 - it('delete.miss renamed', req(UPLOAD_DEST, 404, { method: 'delete' }))
234 - it('delete.ok', req(dirname(UPLOAD_DEST) + '/' + renameTo, 200, { method: 'delete' }))
235 - it('reupload', reqUpload(UPLOAD_DEST, 200))
236 - it('delete.method', req(UPLOAD_DEST, 200, { method: 'DELETE' }))
237 - it('delete.miss deleted', req(UPLOAD_DEST, 404, { method: 'delete' }))
238 - it('upload.too much', reqUpload(UPLOAD_ROOT + 'temp/tooMuch', 400, BIG_CONTENT, BIG_CONTENT.length / 2)) // 400 is caused by nodejs itself, intercepting the mismatch
239 - it('max_dl.account', async () => {
230 + test('rename.ok', reqApi('rename', { uri: UPLOAD_DEST, dest: renameTo }, 200))
231 + test('delete.miss renamed', req(UPLOAD_DEST, 404, { method: 'delete' }))
232 + test('delete.ok', req(dirname(UPLOAD_DEST) + '/' + renameTo, 200, { method: 'delete' }))
233 + test('reupload', reqUpload(UPLOAD_DEST, 200))
234 + test('delete.method', req(UPLOAD_DEST, 200, { method: 'DELETE' }))
235 + test('delete.miss deleted', req(UPLOAD_DEST, 404, { method: 'delete' }))
236 + test('upload.too much', reqUpload(UPLOAD_ROOT + 'temp/tooMuch', 400, BIG_CONTENT, BIG_CONTENT.length / 2)) // 400 is caused by nodejs itself, intercepting the mismatch
237 + test('max_dl.account', async () => {
238 const uri = UPLOAD_ROOT + 'temp/big'
239 await reqUpload(uri, 200, BIG_CONTENT)()
240 await testMaxDl(uri, 2, 1)