var after = require('after'); var assert = require('assert'); var http = require('http'); var fs = require('fs'); var path = require('path'); var request = require('supertest'); var serveIndex = require('..'); var fixtures = path.join(__dirname, '/fixtures'); var relative = path.relative(process.cwd(), fixtures); var skipRelative = ~relative.indexOf('..') || path.resolve(relative) === relative; describe('serveIndex(root)', function () { it('should require root', function () { assert.throws(serveIndex, /root path required/) }) it('should serve text/html without Accept header', function (done) { var server = createServer() request(server) .get('/') .expect('Content-Type', 'text/html; charset=utf-8') .expect(200, done) }) it('should include security header', function (done) { var server = createServer() request(server) .get('/') .expect('X-Content-Type-Options', 'nosniff') .expect(200, done) }) it('should serve a directory index', function (done) { var server = createServer() request(server) .get('/') .expect(200, /todo\.txt/, done) }) it('should work with HEAD requests', function (done) { var server = createServer() request(server) .head('/') .expect(200) .expect(shouldNotHaveBody()) .end(done) }) it('should work with OPTIONS requests', function (done) { var server = createServer() request(server) .options('/') .expect('Allow', 'GET, HEAD, OPTIONS') .expect(200, done) }) it('should deny POST requests', function (done) { var server = createServer() request(server) .post('/') .expect(405, done) }) it('should deny path will NULL byte', function (done) { var server = createServer() request(server) .get('/%00') .expect(400, done) }) it('should deny path that does not decode', function (done) { var server = createServer() request(server) .head('/%FF') .expect(400, done) }) it('should deny path outside root', function (done) { var server = createServer() request(server) .get('/../') .expect(403, done) }) it('should skip non-existent paths', function (done) { var server = createServer() request(server) .get('/bogus') .expect(404, 'Not Found', done) }) it('should treat an ENAMETOOLONG as a 414', function (done) { var dir = path.join(fixtures, Array(10000).join('/foobar')) var server = createServer(dir) request(server) .get('/') .expect(414, done) }) it('should skip non-directories', function (done) { var server = createServer() request(server) .get('/nums') .expect(404, 'Not Found', done) }) describe('when given Accept: header', function () { describe('when Accept: application/json is given', function () { it('should respond with json', function (done) { var server = createServer() request(server) .get('/') .set('Accept', 'application/json') .expect('Content-Type', /json/) .expect(/g# %3 o & %2525 %37 dir/) .expect(/users/) .expect(/file #1\.txt/) .expect(/nums/) .expect(/todo\.txt/) .expect(/さくら\.txt/) .expect(200, done) }); it('should include security header', function (done) { var server = createServer() request(server) .get('/') .set('Accept', 'application/json') .expect('X-Content-Type-Options', 'nosniff') .expect(200, done) }) it('should sort folders first', function (done) { request(createServer()) .get('/') .set('Accept', 'application/json') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') .expect([ '#directory', 'collect', 'g# %3 o & %2525 %37 dir', 'users', 'file #1.txt', 'foo & bar', 'nums', 'todo.txt', 'さくら.txt' ]) .end(done) }) }); describe('when Accept: text/html is given', function () { it('should respond with html', function (done) { var server = createServer() request(server) .get('/') .set('Accept', 'text/html') .expect(200) .expect('Content-Type', 'text/html; charset=utf-8') .expect(/')[1] .split(/')[1] .split(/