You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					645 lines
				
				15 KiB
			
		
		
			
		
	
	
					645 lines
				
				15 KiB
			| 
											3 years ago
										 | 'use strict' | ||
|  | 
 | ||
|  | /* eslint node/no-deprecated-api: "off" */ | ||
|  | 
 | ||
|  | const fs = require('fs') | ||
|  | const path = require('path') | ||
|  | const t = require('tap') | ||
|  | const simple = require('simple-get') | ||
|  | const Fastify = require('fastify') | ||
|  | 
 | ||
|  | const fastifyStatic = require('..') | ||
|  | 
 | ||
|  | const helper = { | ||
|  |   arrange: function (t, options, f) { | ||
|  |     return helper.arrangeModule(t, options, fastifyStatic, f) | ||
|  |   }, | ||
|  |   arrangeModule: function (t, options, mock, f) { | ||
|  |     const fastify = Fastify() | ||
|  |     fastify.register(mock, options) | ||
|  |     t.teardown(fastify.close.bind(fastify)) | ||
|  |     fastify.listen(0, err => { | ||
|  |       t.error(err) | ||
|  |       fastify.server.unref() | ||
|  |       f('http://localhost:' + fastify.server.address().port) | ||
|  |     }) | ||
|  |     return f | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | try { | ||
|  |   fs.mkdirSync(path.join(__dirname, 'static/shallow/empty')) | ||
|  | } catch (error) {} | ||
|  | 
 | ||
|  | t.test('dir list wrong options', t => { | ||
|  |   t.plan(3) | ||
|  | 
 | ||
|  |   const cases = [ | ||
|  |     { | ||
|  |       options: { | ||
|  |         root: path.join(__dirname, '/static'), | ||
|  |         prefix: '/public', | ||
|  |         list: { | ||
|  |           format: 'no-json,no-html' | ||
|  |         } | ||
|  |       }, | ||
|  |       error: new TypeError('The `list.format` option must be json or html') | ||
|  |     }, | ||
|  |     { | ||
|  |       options: { | ||
|  |         root: path.join(__dirname, '/static'), | ||
|  |         list: { | ||
|  |           format: 'html' | ||
|  |           // no render function
 | ||
|  |         } | ||
|  |       }, | ||
|  |       error: new TypeError('The `list.render` option must be a function and is required with html format') | ||
|  |     }, | ||
|  |     { | ||
|  |       options: { | ||
|  |         root: path.join(__dirname, '/static'), | ||
|  |         list: { | ||
|  |           names: 'not-an-array' | ||
|  |         } | ||
|  |       }, | ||
|  |       error: new TypeError('The `list.names` option must be an array') | ||
|  |     } | ||
|  |   ] | ||
|  | 
 | ||
|  |   for (const case_ of cases) { | ||
|  |     const fastify = Fastify() | ||
|  |     fastify.register(fastifyStatic, case_.options) | ||
|  |     fastify.listen(0, err => { | ||
|  |       t.equal(err.message, case_.error.message) | ||
|  |       fastify.server.unref() | ||
|  |     }) | ||
|  |   } | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list default options', t => { | ||
|  |   t.plan(2) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     list: true | ||
|  |   } | ||
|  |   const route = '/public/shallow' | ||
|  |   const content = { dirs: ['empty'], files: ['sample.jpg'] } | ||
|  | 
 | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     t.test(route, t => { | ||
|  |       t.plan(3) | ||
|  |       simple.concat({ | ||
|  |         method: 'GET', | ||
|  |         url: url + route | ||
|  |       }, (err, response, body) => { | ||
|  |         t.error(err) | ||
|  |         t.equal(response.statusCode, 200) | ||
|  |         t.equal(body.toString(), JSON.stringify(content)) | ||
|  |       }) | ||
|  |     }) | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list, custom options', t => { | ||
|  |   t.plan(2) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     index: false, | ||
|  |     list: true | ||
|  |   } | ||
|  | 
 | ||
|  |   const route = '/public/' | ||
|  |   const content = { dirs: ['deep', 'shallow'], files: ['.example', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] } | ||
|  | 
 | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     t.test(route, t => { | ||
|  |       t.plan(3) | ||
|  |       simple.concat({ | ||
|  |         method: 'GET', | ||
|  |         url: url + route | ||
|  |       }, (err, response, body) => { | ||
|  |         t.error(err) | ||
|  |         t.equal(response.statusCode, 200) | ||
|  |         t.equal(body.toString(), JSON.stringify(content)) | ||
|  |       }) | ||
|  |     }) | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list html format', t => { | ||
|  |   t.plan(6) | ||
|  | 
 | ||
|  |   // render html in 2 ways: one with handlebars and one with template string
 | ||
|  | 
 | ||
|  |   const Handlebars = require('handlebars') | ||
|  |   const source = `
 | ||
|  | <html><body> | ||
|  | <ul> | ||
|  | {{#dirs}} | ||
|  |   <li><a href="{{href}}">{{name}}</a></li> | ||
|  | {{/dirs}} | ||
|  | </ul> | ||
|  | <ul> | ||
|  | {{#files}} | ||
|  |   <li><a href="{{href}}" target="_blank">{{name}}</a></li> | ||
|  | {{/files}} | ||
|  | </ul> | ||
|  | </body></html> | ||
|  | `
 | ||
|  |   const handlebarTemplate = Handlebars.compile(source) | ||
|  |   const templates = [ | ||
|  |     { | ||
|  |       render: (dirs, files) => { | ||
|  |         return handlebarTemplate({ dirs, files }) | ||
|  |       }, | ||
|  |       output: `
 | ||
|  | <html><body> | ||
|  | <ul> | ||
|  |   <li><a href="/public/deep">deep</a></li> | ||
|  |   <li><a href="/public/shallow">shallow</a></li> | ||
|  | </ul> | ||
|  | <ul> | ||
|  |   <li><a href="/public/.example" target="_blank">.example</a></li> | ||
|  |   <li><a href="/public/a .md" target="_blank">a .md</a></li> | ||
|  |   <li><a href="/public/foo.html" target="_blank">foo.html</a></li> | ||
|  |   <li><a href="/public/foobar.html" target="_blank">foobar.html</a></li> | ||
|  |   <li><a href="/public/index.css" target="_blank">index.css</a></li> | ||
|  |   <li><a href="/public/index.html" target="_blank">index.html</a></li> | ||
|  | </ul> | ||
|  | </body></html> | ||
|  | `
 | ||
|  |     }, | ||
|  | 
 | ||
|  |     { | ||
|  |       render: (dirs, files) => { | ||
|  |         return `
 | ||
|  | <html><body> | ||
|  | <ul> | ||
|  |   ${dirs.map(dir => `<li><a href="${dir.href}">${dir.name}</a></li>`).join('\n  ')} | ||
|  | </ul> | ||
|  | <ul> | ||
|  |   ${files.map(file => `<li><a href="${file.href}" target="_blank">${file.name}</a></li>`).join('\n  ')} | ||
|  | </ul> | ||
|  | </body></html> | ||
|  | `
 | ||
|  |       }, | ||
|  |       output: `
 | ||
|  | <html><body> | ||
|  | <ul> | ||
|  |   <li><a href="/public/deep">deep</a></li> | ||
|  |   <li><a href="/public/shallow">shallow</a></li> | ||
|  | </ul> | ||
|  | <ul> | ||
|  |   <li><a href="/public/.example" target="_blank">.example</a></li> | ||
|  |   <li><a href="/public/a .md" target="_blank">a .md</a></li> | ||
|  |   <li><a href="/public/foo.html" target="_blank">foo.html</a></li> | ||
|  |   <li><a href="/public/foobar.html" target="_blank">foobar.html</a></li> | ||
|  |   <li><a href="/public/index.css" target="_blank">index.css</a></li> | ||
|  |   <li><a href="/public/index.html" target="_blank">index.html</a></li> | ||
|  | </ul> | ||
|  | </body></html> | ||
|  | `
 | ||
|  |     } | ||
|  | 
 | ||
|  |   ] | ||
|  | 
 | ||
|  |   for (const template of templates) { | ||
|  |     const options = { | ||
|  |       root: path.join(__dirname, '/static'), | ||
|  |       prefix: '/public', | ||
|  |       index: false, | ||
|  |       list: { | ||
|  |         format: 'html', | ||
|  |         names: ['index', 'index.htm'], | ||
|  |         render: template.render | ||
|  |       } | ||
|  |     } | ||
|  |     const routes = ['/public/index.htm', '/public/index'] | ||
|  | 
 | ||
|  |     // check all routes by names
 | ||
|  | 
 | ||
|  |     helper.arrange(t, options, (url) => { | ||
|  |       for (const route of routes) { | ||
|  |         t.test(route, t => { | ||
|  |           t.plan(3) | ||
|  |           simple.concat({ | ||
|  |             method: 'GET', | ||
|  |             url: url + route | ||
|  |           }, (err, response, body) => { | ||
|  |             t.error(err) | ||
|  |             t.equal(response.statusCode, 200) | ||
|  |             t.equal(body.toString(), template.output) | ||
|  |           }) | ||
|  |         }) | ||
|  |       } | ||
|  |     }) | ||
|  |   } | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list href nested structure', t => { | ||
|  |   t.plan(6) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     index: false, | ||
|  |     list: { | ||
|  |       format: 'html', | ||
|  |       names: ['index', 'index.htm'], | ||
|  |       render (dirs, files) { | ||
|  |         return dirs[0].href | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   const routes = [ | ||
|  |     { path: '/public/', response: '/public/deep' }, | ||
|  |     { path: '/public/index', response: '/public/deep' }, | ||
|  |     { path: '/public/deep/', response: '/public/deep/path' }, | ||
|  |     { path: '/public/deep/index.htm', response: '/public/deep/path' }, | ||
|  |     { path: '/public/deep/path/', response: '/public/deep/path/for' } | ||
|  |   ] | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     for (const route of routes) { | ||
|  |       t.test(route.path, t => { | ||
|  |         t.plan(5) | ||
|  |         simple.concat({ | ||
|  |           method: 'GET', | ||
|  |           url: url + route.path | ||
|  |         }, (err, response, body) => { | ||
|  |           t.error(err) | ||
|  |           t.equal(response.statusCode, 200) | ||
|  |           t.equal(body.toString(), route.response) | ||
|  |           simple.concat({ | ||
|  |             method: 'GET', | ||
|  |             url: url + body.toString() | ||
|  |           }, (err, response, body) => { | ||
|  |             t.error(err) | ||
|  |             t.equal(response.statusCode, 200) | ||
|  |           }) | ||
|  |         }) | ||
|  |       }) | ||
|  |     } | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list html format - stats', t => { | ||
|  |   t.plan(7) | ||
|  | 
 | ||
|  |   const options1 = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     index: false, | ||
|  |     list: { | ||
|  |       format: 'html', | ||
|  |       render (dirs, files) { | ||
|  |         t.ok(dirs.length > 0) | ||
|  |         t.ok(files.length > 0) | ||
|  | 
 | ||
|  |         t.ok(dirs.every(every)) | ||
|  |         t.ok(files.every(every)) | ||
|  | 
 | ||
|  |         function every (value) { | ||
|  |           return value.stats && | ||
|  |             value.stats.atime && | ||
|  |             !value.extendedInfo | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   const route = '/public/' | ||
|  | 
 | ||
|  |   helper.arrange(t, options1, (url) => { | ||
|  |     simple.concat({ | ||
|  |       method: 'GET', | ||
|  |       url: url + route | ||
|  |     }, (err, response, body) => { | ||
|  |       t.error(err) | ||
|  |       t.equal(response.statusCode, 200) | ||
|  |     }) | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list html format - extended info', t => { | ||
|  |   t.plan(4) | ||
|  | 
 | ||
|  |   const route = '/public/' | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     index: false, | ||
|  |     list: { | ||
|  |       format: 'html', | ||
|  |       extendedFolderInfo: true, | ||
|  |       render (dirs, files) { | ||
|  |         t.test('dirs', t => { | ||
|  |           t.plan(dirs.length * 7) | ||
|  | 
 | ||
|  |           for (const value of dirs) { | ||
|  |             t.ok(value.extendedInfo) | ||
|  | 
 | ||
|  |             t.equal(typeof value.extendedInfo.fileCount, 'number') | ||
|  |             t.equal(typeof value.extendedInfo.totalFileCount, 'number') | ||
|  |             t.equal(typeof value.extendedInfo.folderCount, 'number') | ||
|  |             t.equal(typeof value.extendedInfo.totalFolderCount, 'number') | ||
|  |             t.equal(typeof value.extendedInfo.totalSize, 'number') | ||
|  |             t.equal(typeof value.extendedInfo.lastModified, 'number') | ||
|  |           } | ||
|  |         }) | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     simple.concat({ | ||
|  |       method: 'GET', | ||
|  |       url: url + route | ||
|  |     }, (err, response, body) => { | ||
|  |       t.error(err) | ||
|  |       t.equal(response.statusCode, 200) | ||
|  |     }) | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list json format', t => { | ||
|  |   t.plan(2) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     prefixAvoidTrailingSlash: true, | ||
|  |     list: { | ||
|  |       format: 'json', | ||
|  |       names: ['index', 'index.json', '/'] | ||
|  |     } | ||
|  |   } | ||
|  |   // const routes = ['/public/shallow', 'public/shallow/', '/public/shallow/index.json', '/public/shallow/index']
 | ||
|  |   const routes = ['/public/shallow/'] | ||
|  |   const content = { dirs: ['empty'], files: ['sample.jpg'] } | ||
|  | 
 | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     for (const route of routes) { | ||
|  |       t.test(route, t => { | ||
|  |         t.plan(3) | ||
|  |         simple.concat({ | ||
|  |           method: 'GET', | ||
|  |           url: url + route | ||
|  |         }, (err, response, body) => { | ||
|  |           t.error(err) | ||
|  |           t.equal(response.statusCode, 200) | ||
|  |           t.equal(body.toString(), JSON.stringify(content)) | ||
|  |         }) | ||
|  |       }) | ||
|  |     } | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list json format - extended info', t => { | ||
|  |   t.plan(2) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     prefixAvoidTrailingSlash: true, | ||
|  |     list: { | ||
|  |       format: 'json', | ||
|  |       names: ['index', 'index.json', '/'], | ||
|  |       extendedFolderInfo: true, | ||
|  |       jsonFormat: 'extended' | ||
|  | 
 | ||
|  |     } | ||
|  |   } | ||
|  |   const routes = ['/public/shallow/'] | ||
|  | 
 | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     for (const route of routes) { | ||
|  |       t.test(route, t => { | ||
|  |         t.plan(5) | ||
|  |         simple.concat({ | ||
|  |           method: 'GET', | ||
|  |           url: url + route | ||
|  |         }, (err, response, body) => { | ||
|  |           t.error(err) | ||
|  |           t.equal(response.statusCode, 200) | ||
|  |           const bodyObject = JSON.parse(body.toString()) | ||
|  |           t.equal(bodyObject.dirs[0].name, 'empty') | ||
|  |           t.equal(typeof bodyObject.dirs[0].stats.atime, 'string') | ||
|  |           t.equal(typeof bodyObject.dirs[0].extendedInfo.totalSize, 'number') | ||
|  |         }) | ||
|  |       }) | ||
|  |     } | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list - url parameter format', t => { | ||
|  |   t.plan(13) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     index: false, | ||
|  |     list: { | ||
|  |       format: 'html', | ||
|  |       render (dirs, files) { | ||
|  |         return 'html' | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  |   const route = '/public/' | ||
|  | 
 | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     simple.concat({ | ||
|  |       method: 'GET', | ||
|  |       url: url + route | ||
|  |     }, (err, response, body) => { | ||
|  |       t.error(err) | ||
|  |       t.equal(response.statusCode, 200) | ||
|  |       t.equal(body.toString(), 'html') | ||
|  |       t.ok(response.headers['content-type'].includes('text/html')) | ||
|  |     }) | ||
|  | 
 | ||
|  |     simple.concat({ | ||
|  |       method: 'GET', | ||
|  |       url: url + route + '?format=html' | ||
|  |     }, (err, response, body) => { | ||
|  |       t.error(err) | ||
|  |       t.equal(response.statusCode, 200) | ||
|  |       t.equal(body.toString(), 'html') | ||
|  |       t.ok(response.headers['content-type'].includes('text/html')) | ||
|  |     }) | ||
|  | 
 | ||
|  |     simple.concat({ | ||
|  |       method: 'GET', | ||
|  |       url: url + route + '?format=json' | ||
|  |     }, (err, response, body) => { | ||
|  |       t.error(err) | ||
|  |       t.equal(response.statusCode, 200) | ||
|  |       t.ok(body.toString()) | ||
|  |       t.ok(response.headers['content-type'].includes('application/json')) | ||
|  |     }) | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list on empty dir', t => { | ||
|  |   t.plan(2) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     list: true | ||
|  |   } | ||
|  |   const route = '/public/shallow/empty' | ||
|  |   const content = { dirs: [], files: [] } | ||
|  | 
 | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     t.test(route, t => { | ||
|  |       t.plan(3) | ||
|  |       simple.concat({ | ||
|  |         method: 'GET', | ||
|  |         url: url + route | ||
|  |       }, (err, response, body) => { | ||
|  |         t.error(err) | ||
|  |         t.equal(response.statusCode, 200) | ||
|  |         t.equal(body.toString(), JSON.stringify(content)) | ||
|  |       }) | ||
|  |     }) | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list serve index.html on index option', t => { | ||
|  |   t.plan(2) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     index: false, | ||
|  |     list: { | ||
|  |       format: 'html', | ||
|  |       names: ['index', 'index.html'], | ||
|  |       render: () => 'dir list index' | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     t.test('serve index.html from fs', t => { | ||
|  |       t.plan(6) | ||
|  | 
 | ||
|  |       let route = '/public/index.html' | ||
|  | 
 | ||
|  |       simple.concat({ | ||
|  |         method: 'GET', | ||
|  |         url: url + route | ||
|  |       }, (err, response, body) => { | ||
|  |         t.error(err) | ||
|  |         t.equal(response.statusCode, 200) | ||
|  |         t.equal(body.toString(), '<html>\n  <body>\n    the body\n  </body>\n</html>\n') | ||
|  |       }) | ||
|  | 
 | ||
|  |       route = '/public/index' | ||
|  |       simple.concat({ | ||
|  |         method: 'GET', | ||
|  |         url: url + route | ||
|  |       }, (err, response, body) => { | ||
|  |         t.error(err) | ||
|  |         t.equal(response.statusCode, 200) | ||
|  |         t.equal(body.toString(), 'dir list index') | ||
|  |       }) | ||
|  |     }) | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('serve a non existent dir and get error', t => { | ||
|  |   t.plan(2) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: '/none', | ||
|  |     prefix: '/public', | ||
|  |     list: true | ||
|  |   } | ||
|  |   const route = '/public/' | ||
|  | 
 | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     t.test(route, t => { | ||
|  |       t.plan(2) | ||
|  |       simple.concat({ | ||
|  |         method: 'GET', | ||
|  |         url: url + route | ||
|  |       }, (err, response, body) => { | ||
|  |         t.error(err) | ||
|  |         t.equal(response.statusCode, 404) | ||
|  |       }) | ||
|  |     }) | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('serve a non existent dir and get error', t => { | ||
|  |   t.plan(2) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     list: { | ||
|  |       names: ['index'] | ||
|  |     } | ||
|  |   } | ||
|  |   const route = '/public/none/index' | ||
|  | 
 | ||
|  |   helper.arrange(t, options, (url) => { | ||
|  |     t.test(route, t => { | ||
|  |       t.plan(2) | ||
|  |       simple.concat({ | ||
|  |         method: 'GET', | ||
|  |         url: url + route | ||
|  |       }, (err, response, body) => { | ||
|  |         t.error(err) | ||
|  |         t.equal(response.statusCode, 404) | ||
|  |       }) | ||
|  |     }) | ||
|  |   }) | ||
|  | }) | ||
|  | 
 | ||
|  | t.test('dir list error', t => { | ||
|  |   t.plan(7) | ||
|  | 
 | ||
|  |   const options = { | ||
|  |     root: path.join(__dirname, '/static'), | ||
|  |     prefix: '/public', | ||
|  |     prefixAvoidTrailingSlash: true, | ||
|  |     index: false, | ||
|  |     list: { | ||
|  |       format: 'html', | ||
|  |       names: ['index', 'index.htm'], | ||
|  |       render: () => '' | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   const errorMessage = 'mocking send' | ||
|  |   const dirList = require('../lib/dirList') | ||
|  |   dirList.send = async () => { throw new Error(errorMessage) } | ||
|  | 
 | ||
|  |   const mock = t.mock('..', { | ||
|  |     '../lib/dirList.js': dirList | ||
|  |   }) | ||
|  | 
 | ||
|  |   const routes = ['/public/', '/public/index.htm'] | ||
|  | 
 | ||
|  |   helper.arrangeModule(t, options, mock, (url) => { | ||
|  |     for (const route of routes) { | ||
|  |       simple.concat({ | ||
|  |         method: 'GET', | ||
|  |         url: url + route | ||
|  |       }, (err, response, body) => { | ||
|  |         t.error(err) | ||
|  |         t.equal(JSON.parse(body.toString()).message, errorMessage) | ||
|  |         t.equal(response.statusCode, 500) | ||
|  |       }) | ||
|  |     } | ||
|  |   }) | ||
|  | }) |