diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index 3a34b4e58..ecf2dd9d2 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -59,7 +59,7 @@ function getXUACompatibleUrl (url) { } function createKarmaMiddleware ( - filesPromise, + currentWebFiles, serveStaticFile, serveFile, injector, @@ -132,119 +132,114 @@ function createKarmaMiddleware ( const isRequestingDebugFile = requestUrl === '/debug.html' const isRequestingClientContextFile = requestUrl === '/client_with_context.html' if (isRequestingContextFile || isRequestingDebugFile || isRequestingClientContextFile) { - return filesPromise.then((files) => { - let fileServer - let requestedFileUrl - log.debug('custom files', customContextFile, customDebugFile, customClientContextFile) - if (isRequestingContextFile && customContextFile) { - log.debug(`Serving customContextFile ${customContextFile}`) - fileServer = serveFile - requestedFileUrl = customContextFile - } else if (isRequestingDebugFile && customDebugFile) { - log.debug(`Serving customDebugFile ${customDebugFile}`) - fileServer = serveFile - requestedFileUrl = customDebugFile - } else if (isRequestingClientContextFile && customClientContextFile) { - log.debug(`Serving customClientContextFile ${customClientContextFile}`) - fileServer = serveFile - requestedFileUrl = customClientContextFile - } else { - log.debug(`Serving static request ${requestUrl}`) - fileServer = serveStaticFile - requestedFileUrl = requestUrl - } - - fileServer(requestedFileUrl, requestedRangeHeader, response, function (data) { - common.setNoCacheHeaders(response) - - const scriptTags = [] - for (const file of files.included) { - let filePath = file.path - const fileType = file.type || file.detectType() + let fileServer + let requestedFileUrl + log.debug('custom files', customContextFile, customDebugFile, customClientContextFile) + if (isRequestingContextFile && customContextFile) { + log.debug(`Serving customContextFile ${customContextFile}`) + fileServer = serveFile + requestedFileUrl = customContextFile + } else if (isRequestingDebugFile && customDebugFile) { + log.debug(`Serving customDebugFile ${customDebugFile}`) + fileServer = serveFile + requestedFileUrl = customDebugFile + } else if (isRequestingClientContextFile && customClientContextFile) { + log.debug(`Serving customClientContextFile ${customClientContextFile}`) + fileServer = serveFile + requestedFileUrl = customClientContextFile + } else { + log.debug(`Serving static request ${requestUrl}`) + fileServer = serveStaticFile + requestedFileUrl = requestUrl + } - if (!FILE_TYPES.includes(fileType)) { - if (file.type == null) { - log.warn( - 'Unable to determine file type from the file extension, defaulting to js.\n' + - ` To silence the warning specify a valid type for ${file.originalPath} in the configuration file.\n` + - ' See http://karma-runner.github.io/latest/config/files.html' - ) - } else { - log.warn(`Invalid file type (${file.type || 'empty string'}), defaulting to js.`) - } + fileServer(requestedFileUrl, requestedRangeHeader, response, function (data) { + common.setNoCacheHeaders(response) + const scriptTags = [] + for (const file of currentWebFiles.included) { + let filePath = file.path + const fileType = file.type || file.detectType() + + if (!FILE_TYPES.includes(fileType)) { + if (file.type == null) { + log.warn( + 'Unable to determine file type from the file extension, defaulting to js.\n' + + ` To silence the warning specify a valid type for ${file.originalPath} in the configuration file.\n` + + ' See http://karma-runner.github.io/latest/config/files.html' + ) + } else { + log.warn(`Invalid file type (${file.type || 'empty string'}), defaulting to js.`) } + } - if (!file.isUrl) { - filePath = filePathToUrlPath(filePath, basePath, urlRoot, proxyPath) + if (!file.isUrl) { + filePath = filePathToUrlPath(filePath, basePath, urlRoot, proxyPath) - if (requestUrl === '/context.html') { - filePath += '?' + file.sha - } + if (requestUrl === '/context.html') { + filePath += '?' + file.sha } + } - if (fileType === 'css') { - scriptTags.push(``) - } else if (fileType === 'dom') { - scriptTags.push(file.content) - } else if (fileType === 'html') { - scriptTags.push(``) + if (fileType === 'css') { + scriptTags.push(``) + } else if (fileType === 'dom') { + scriptTags.push(file.content) + } else if (fileType === 'html') { + scriptTags.push(``) + } else { + const scriptType = (SCRIPT_TYPE[fileType] || 'text/javascript') + const crossOriginAttribute = includeCrossOriginAttribute ? 'crossorigin="anonymous"' : '' + if (fileType === 'module') { + scriptTags.push(``) } else { - const scriptType = (SCRIPT_TYPE[fileType] || 'text/javascript') - const crossOriginAttribute = includeCrossOriginAttribute ? 'crossorigin="anonymous"' : '' - if (fileType === 'module') { - scriptTags.push(``) - } else { - scriptTags.push(``) - } + scriptTags.push(``) } } + } - const scriptUrls = [] - // For client_with_context, html elements are not added directly through an iframe. - // Instead, scriptTags is stored to window.__karma__.scriptUrls first. Later, the - // client will read window.__karma__.scriptUrls and dynamically add them to the DOM - // using DOMParser. - if (requestUrl === '/client_with_context.html') { - for (const script of scriptTags) { - scriptUrls.push( - // Escape characters with special roles (tags) in HTML. Open angle brackets are parsed as tags - // immediately, even if it is within double quotations in browsers - script.replace(//g, '\\x3E')) - } + const scriptUrls = [] + // For client_with_context, html elements are not added directly through an iframe. + // Instead, scriptTags is stored to window.__karma__.scriptUrls first. Later, the + // client will read window.__karma__.scriptUrls and dynamically add them to the DOM + // using DOMParser. + if (requestUrl === '/client_with_context.html') { + for (const script of scriptTags) { + scriptUrls.push( + // Escape characters with special roles (tags) in HTML. Open angle brackets are parsed as tags + // immediately, even if it is within double quotations in browsers + script.replace(//g, '\\x3E')) } + } - const mappings = data.includes('%MAPPINGS%') ? files.served.map((file) => { - const filePath = filePathToUrlPath(file.path, basePath, urlRoot, proxyPath) - .replace(/\\/g, '\\\\') // Windows paths contain backslashes and generate bad IDs if not escaped - .replace(/'/g, '\\\'') // Escape single quotes - double quotes should not be allowed! + const mappings = data.includes('%MAPPINGS%') ? currentWebFiles.served.map((file) => { + const filePath = filePathToUrlPath(file.path, basePath, urlRoot, proxyPath) + .replace(/\\/g, '\\\\') // Windows paths contain backslashes and generate bad IDs if not escaped + .replace(/'/g, '\\\'') // Escape single quotes - double quotes should not be allowed! - return ` '${filePath}': '${file.sha}'` - }) : [] + return ` '${filePath}': '${file.sha}'` + }) : [] - return data - .replace('%SCRIPTS%', scriptTags.join('\n')) - .replace('%CLIENT_CONFIG%', 'window.__karma__.config = ' + JSON.stringify(client) + ';\n') - .replace('%SCRIPT_URL_ARRAY%', 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n') - .replace('%MAPPINGS%', 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n') - .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) - }) + return data + .replace('%SCRIPTS%', scriptTags.join('\n')) + .replace('%CLIENT_CONFIG%', 'window.__karma__.config = ' + JSON.stringify(client) + ';\n') + .replace('%SCRIPT_URL_ARRAY%', 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n') + .replace('%MAPPINGS%', 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n') + .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) }) } else if (requestUrl === '/context.json') { - return filesPromise.then((files) => { - common.setNoCacheHeaders(response) - response.writeHead(200) - response.end(JSON.stringify({ - files: files.included.map((file) => filePathToUrlPath(file.path + '?' + file.sha, basePath, urlRoot, proxyPath)) - })) - }) + common.setNoCacheHeaders(response) + response.writeHead(200) + response.end(JSON.stringify({ + files: currentWebFiles.included.map((file) => filePathToUrlPath(file.path + '?' + file.sha, basePath, urlRoot, proxyPath)) + })) + } else { + next() } - - return next() } } createKarmaMiddleware.$inject = [ - 'filesPromise', + 'currentWebFiles', 'serveStaticFile', 'serveFile', 'injector', diff --git a/lib/middleware/source_files.js b/lib/middleware/source_files.js index e44ae021d..3181d795b 100644 --- a/lib/middleware/source_files.js +++ b/lib/middleware/source_files.js @@ -18,7 +18,7 @@ function composeUrl (url, basePath, urlRoot) { } // Source Files middleware is responsible for serving all the source files under the test. -function createSourceFilesMiddleware (filesPromise, serveFile, basePath, urlRoot) { +function createSourceFilesMiddleware (currentWebFiles, serveFile, basePath, urlRoot) { return function (request, response, next) { const requestedFilePath = composeUrl(request.url, basePath, urlRoot) // When a path contains HTML-encoded characters (e.g %2F used by Jenkins for branches with /) @@ -29,39 +29,37 @@ function createSourceFilesMiddleware (filesPromise, serveFile, basePath, urlRoot log.debug(`Requesting ${request.url}`) log.debug(`Fetching ${requestedFilePath}`) - return filesPromise.then(function (files) { - // TODO(vojta): change served to be a map rather then an array - const file = findByPath(files.served, requestedFilePath) || findByPath(files.served, requestedFilePathUnescaped) - const rangeHeader = request.headers.range + // TODO(vojta): change served to be a map rather then an array + const file = findByPath(currentWebFiles.served, requestedFilePath) || findByPath(currentWebFiles.served, requestedFilePathUnescaped) + const rangeHeader = request.headers.range - if (file) { - const acceptEncodingHeader = request.headers['accept-encoding'] - const matchedEncoding = Object.keys(file.encodings).find( - (encoding) => new RegExp(`(^|.*, ?)${encoding}(,|$)`).test(acceptEncodingHeader) - ) - const content = file.encodings[matchedEncoding] || file.content + if (file) { + const acceptEncodingHeader = request.headers['accept-encoding'] + const matchedEncoding = Object.keys(file.encodings).find( + (encoding) => new RegExp(`(^|.*, ?)${encoding}(,|$)`).test(acceptEncodingHeader) + ) + const content = file.encodings[matchedEncoding] || file.content - serveFile(file.contentPath || file.path, rangeHeader, response, function () { - if (/\?\w+/.test(request.url)) { - common.setHeavyCacheHeaders(response) // files with timestamps - cache one year, rely on timestamps - } else { - common.setNoCacheHeaders(response) // without timestamps - no cache (debug) - } - if (matchedEncoding) { - response.setHeader('Content-Encoding', matchedEncoding) - } - }, content, file.doNotCache) - } else { - next() - } + serveFile(file.contentPath || file.path, rangeHeader, response, function () { + if (/\?\w+/.test(request.url)) { + common.setHeavyCacheHeaders(response) // files with timestamps - cache one year, rely on timestamps + } else { + common.setNoCacheHeaders(response) // without timestamps - no cache (debug) + } + if (matchedEncoding) { + response.setHeader('Content-Encoding', matchedEncoding) + } + }, content, file.doNotCache) + } else { + next() + } - request.resume() - }) + request.resume() } } createSourceFilesMiddleware.$inject = [ - 'filesPromise', 'serveFile', 'config.basePath', 'config.urlRoot' + 'currentWebFiles', 'serveFile', 'config.basePath', 'config.urlRoot' ] exports.create = createSourceFilesMiddleware diff --git a/lib/server.js b/lib/server.js index aa96b76ea..3f4f186de 100644 --- a/lib/server.js +++ b/lib/server.js @@ -21,6 +21,7 @@ const createServeFile = require('./web-server').createServeFile const createServeStaticFile = require('./web-server').createServeStaticFile const createFilesPromise = require('./web-server').createFilesPromise const createWebServer = require('./web-server').createWebServer +const createWebFiles = require('./web-files').createWebFiles const preprocessor = require('./preprocessor') const Launcher = require('./launcher').Launcher const FileList = require('./file-list') @@ -82,7 +83,10 @@ class Server extends KarmaEventEmitter { webServer: ['factory', createWebServer], serveFile: ['factory', createServeFile], serveStaticFile: ['factory', createServeStaticFile], + // Obsolete, do not use filesPromise: ['factory', createFilesPromise], + // The files to be included/served to browser for test + currentWebFiles: ['factory', createWebFiles], socketServer: ['factory', createSocketIoServer], executor: ['factory', Executor.factory], // TODO: Deprecated. Remove in the next major @@ -343,8 +347,8 @@ class Server extends KarmaEventEmitter { } if (config.autoWatch) { - this.on('file_list_modified', () => { - this.log.debug('List of files has changed, trying to execute') + this.on('web_files_modified', () => { + this.log.debug('List of included/served files has changed, trying to execute') if (config.restartOnFileChange) { socketServer.sockets.emit('stop') } diff --git a/test/unit/middleware/karma.spec.js b/test/unit/middleware/karma.spec.js index 8a968262c..ba2dcb6fe 100644 --- a/test/unit/middleware/karma.spec.js +++ b/test/unit/middleware/karma.spec.js @@ -2,7 +2,6 @@ const mocks = require('mocks') -const helper = require('../../../lib/helper') const constants = require('../../../lib/constants') const File = require('../../../lib/file') const Url = require('../../../lib/url') @@ -12,7 +11,7 @@ const HttpRequestMock = mocks.http.ServerRequest describe('middleware.karma', () => { let serveFile - let filesDeferred + let currentWebFiles let nextSpy let response @@ -37,7 +36,7 @@ describe('middleware.karma', () => { const createServeFile = require('../../../lib/middleware/common').createServeFile const createKarmaMiddleware = require('../../../lib/middleware/karma').create - let handler = serveFile = filesDeferred = nextSpy = response = null + let handler = serveFile = currentWebFiles = nextSpy = response = null const clientConfig = { foo: 'bar' @@ -58,10 +57,10 @@ describe('middleware.karma', () => { beforeEach(() => { nextSpy = sinon.spy() response = new HttpResponseMock() - filesDeferred = helper.defer() + currentWebFiles = { included: [], served: [] } serveFile = createServeFile(fsMock, '/karma/static') handler = createKarmaMiddleware( - filesDeferred.promise, + currentWebFiles, serveFile, null, injector, @@ -71,15 +70,6 @@ describe('middleware.karma', () => { ) }) - // helpers - const includedFiles = (files) => { - return filesDeferred.resolve({ included: files, served: [] }) - } - - const servedFiles = (files) => { - return filesDeferred.resolve({ included: [], served: files }) - } - const normalizedHttpRequest = (urlPath) => { const req = new HttpRequestMock(urlPath) req.normalizedUrl = req.url @@ -121,7 +111,7 @@ describe('middleware.karma', () => { it('should serve client.html', (done) => { handler = createKarmaMiddleware( - null, + currentWebFiles, serveFile, null, injector, @@ -140,7 +130,7 @@ describe('middleware.karma', () => { it('should serve /?id=xxx', (done) => { handler = createKarmaMiddleware( - null, + currentWebFiles, serveFile, null, injector, @@ -159,7 +149,7 @@ describe('middleware.karma', () => { it('should serve /?x-ua-compatible with replaced values', (done) => { handler = createKarmaMiddleware( - null, + currentWebFiles, serveFile, null, injector, @@ -177,7 +167,7 @@ describe('middleware.karma', () => { }) it('should serve debug.html/?x-ua-compatible with replaced values', (done) => { - includedFiles([]) + currentWebFiles.included = [] response.once('end', () => { expect(nextSpy).not.to.have.been.called @@ -200,10 +190,10 @@ describe('middleware.karma', () => { }) it('should serve context.html with replaced script tags', (done) => { - includedFiles([ + currentWebFiles.included = [ new MockFile('/first.js', 'sha123'), new MockFile('/second.js', 'sha456') - ]) + ] response.once('end', () => { expect(nextSpy).not.to.have.been.called @@ -215,14 +205,14 @@ describe('middleware.karma', () => { }) it('should serve context.html with replaced link tags', (done) => { - includedFiles([ + currentWebFiles.included = [ new MockFile('/first.css', 'sha007'), new MockFile('/second.html', 'sha678'), new MockFile('/third', 'sha111', 'css'), new MockFile('/fourth', 'sha222', 'html'), new Url('http://some.url.com/fifth', 'css'), new Url('http://some.url.com/sixth', 'html') - ]) + ] response.once('end', () => { expect(nextSpy).not.to.have.been.called @@ -234,10 +224,10 @@ describe('middleware.karma', () => { }) it('should serve context.html with the correct path for the script tags', (done) => { - includedFiles([ + currentWebFiles.included = [ new MockFile('/some/abc/a.js', 'sha'), new MockFile('/base/path/b.js', 'shaaa') - ]) + ] response.once('end', () => { expect(nextSpy).not.to.have.been.called @@ -249,7 +239,7 @@ describe('middleware.karma', () => { }) it('should serve context.html with the correct path for link tags', (done) => { - includedFiles([ + currentWebFiles.included = [ new MockFile('/some/abc/a.css', 'sha1'), new MockFile('/base/path/b.css', 'sha2'), new MockFile('/some/abc/c.html', 'sha3'), @@ -258,7 +248,7 @@ describe('middleware.karma', () => { new MockFile('/base/path/f', 'sha6', 'css'), new MockFile('/some/abc/g', 'sha7', 'html'), new MockFile('/base/path/h', 'sha8', 'html') - ]) + ] response.once('end', () => { expect(nextSpy).not.to.have.been.called @@ -270,9 +260,9 @@ describe('middleware.karma', () => { }) it('should serve context.html with included DOM content', (done) => { - filesDeferred = helper.defer() + currentWebFiles = { included: [], served: [] } handler = createKarmaMiddleware( - filesDeferred.promise, + currentWebFiles, serveFile, null, injector, @@ -280,11 +270,11 @@ describe('middleware.karma', () => { '/' ) - includedFiles([ + currentWebFiles.included = [ new MockFile('/some/abc/a.dom', 'sha1', undefined, 'a'), new MockFile('/some/abc/b_test_dom.html', 'sha2', 'dom', 'b'), new MockFile('/some/abc/c', 'sha3', 'dom', 'c') - ]) + ] response.once('end', () => { expect(nextSpy).not.to.have.been.called @@ -296,7 +286,7 @@ describe('middleware.karma', () => { }) it('should serve context.json with the correct paths for all files', (done) => { - includedFiles([ + currentWebFiles.included = [ new MockFile('/some/abc/a.css', 'sha1'), new MockFile('/base/path/b.css', 'sha2'), new MockFile('/some/abc/c.html', 'sha3'), @@ -305,7 +295,7 @@ describe('middleware.karma', () => { new MockFile('/base/path/f', 'sha6', 'css'), new MockFile('/some/abc/g', 'sha7', 'html'), new MockFile('/base/path/h', 'sha8', 'html') - ]) + ] response.once('end', () => { expect(nextSpy).not.to.have.been.called @@ -328,9 +318,9 @@ describe('middleware.karma', () => { }) it('should not change urls', (done) => { - includedFiles([ + currentWebFiles.included = [ new Url('http://some.url.com/whatever') - ]) + ] response.once('end', () => { expect(response).to.beServedAs(200, 'CONTEXT\n') @@ -343,7 +333,7 @@ describe('middleware.karma', () => { it('should send non-caching headers for context.html', (done) => { const ZERO_DATE = (new Date(0)).toUTCString() - includedFiles([]) + currentWebFiles.included = [] response.once('end', () => { expect(nextSpy).not.to.have.been.called @@ -359,11 +349,11 @@ describe('middleware.karma', () => { it('should inline mappings with all served files', (done) => { fsMock._touchFile('/karma/static/context.html', 0, '%MAPPINGS%') - servedFiles([ + currentWebFiles.served = [ new MockFile('/some/abc/a.js', 'sha_a'), new MockFile('/base/path/b.js', 'sha_b'), new MockFile('\\windows\\path\\uuu\\c.js', 'sha_c') - ]) + ] response.once('end', () => { expect(response).to.beServedAs(200, "window.__karma__.files = {\n '/__proxy__/__karma__/absolute/some/abc/a.js': 'sha_a',\n '/__proxy__/__karma__/base/b.js': 'sha_b',\n '/__proxy__/__karma__/absolute\\\\windows\\\\path\\\\uuu\\\\c.js': 'sha_c'\n};\n") @@ -375,10 +365,10 @@ describe('middleware.karma', () => { it('should escape quotes in mappings with all served files', (done) => { fsMock._touchFile('/karma/static/context.html', 0, '%MAPPINGS%') - servedFiles([ + currentWebFiles.served = [ new MockFile("/some/abc/a'b.js", 'sha_a'), new MockFile('/base/path/ba.js', 'sha_b') - ]) + ] response.once('end', () => { expect(response).to.beServedAs(200, 'window.__karma__.files = {\n \'/__proxy__/__karma__/absolute/some/abc/a\\\'b.js\': \'sha_a\',\n \'/__proxy__/__karma__/base/ba.js\': \'sha_b\'\n};\n') @@ -389,10 +379,10 @@ describe('middleware.karma', () => { }) it('should serve debug.html with replaced script tags without timestamps', (done) => { - includedFiles([ + currentWebFiles.included = [ new MockFile('/first.js'), new MockFile('/base/path/b.js') - ]) + ] response.once('end', () => { expect(nextSpy).not.to.have.been.called @@ -404,7 +394,7 @@ describe('middleware.karma', () => { }) it('should serve debug.html with replaced link tags without timestamps', (done) => { - includedFiles([ + currentWebFiles.included = [ new MockFile('/first.css'), new MockFile('/base/path/b.css'), new MockFile('/second.html'), @@ -413,7 +403,7 @@ describe('middleware.karma', () => { new MockFile('/base/path/f', null, 'css'), new MockFile('/fourth', null, 'html'), new MockFile('/base/path/g', null, 'html') - ]) + ] response.once('end', () => { expect(nextSpy).not.to.have.been.called @@ -425,9 +415,9 @@ describe('middleware.karma', () => { }) it('should inline client config to debug.html', (done) => { - includedFiles([ + currentWebFiles.included = [ new MockFile('/first.js') - ]) + ] fsMock._touchFile('/karma/static/debug.html', 1, '%CLIENT_CONFIG%') response.once('end', () => { @@ -439,7 +429,7 @@ describe('middleware.karma', () => { }) it('should not serve other files even if they are in urlRoot', (done) => { - includedFiles([]) + currentWebFiles.included = [] callHandlerWith('/__karma__/something/else.js', () => { expect(response).to.beNotServed() @@ -450,7 +440,7 @@ describe('middleware.karma', () => { it('should update handle updated configs', (done) => { let i = 0 handler = createKarmaMiddleware( - filesDeferred.promise, + currentWebFiles, serveFile, null, { @@ -472,20 +462,20 @@ describe('middleware.karma', () => { { path: '/__proxy__/' } ) - includedFiles([ + currentWebFiles.included = [ new MockFile('/first.js') - ]) + ] fsMock._touchFile('/karma/static/debug.html', 1, '%CLIENT_CONFIG%') response.once('end', () => { expect(response).to.beServedAs(200, 'window.__karma__.config = {"foo":"bar"};\n') response = new HttpResponseMock() - callHandlerWith('/__karma__/debug.html') response.once('end', () => { expect(response).to.beServedAs(200, 'window.__karma__.config = {"foo":"baz"};\n') done() }) + callHandlerWith('/__karma__/debug.html') }) callHandlerWith('/__karma__/debug.html') diff --git a/test/unit/middleware/source_files.spec.js b/test/unit/middleware/source_files.spec.js index 8da227eed..f272fc678 100644 --- a/test/unit/middleware/source_files.spec.js +++ b/test/unit/middleware/source_files.spec.js @@ -3,15 +3,14 @@ const mocks = require('mocks') const request = require('supertest') var zlib = require('zlib') -const helper = require('../../../lib/helper') const File = require('../../../lib/file') const createServeFile = require('../../../lib/middleware/common').createServeFile const createSourceFilesMiddleware = require('../../../lib/middleware/source_files').create describe('middleware.source_files', function () { let next - let files - let server = next = files = null + let currentWebFiles + let server = next = currentWebFiles = null const fsMock = mocks.fs.create({ base: { @@ -34,7 +33,7 @@ describe('middleware.source_files', function () { const serveFile = createServeFile(fsMock, null) function createServer (f, s, basePath) { - const handler = createSourceFilesMiddleware(f.promise, s, basePath) + const handler = createSourceFilesMiddleware(f, s, basePath) return http.createServer(function (req, res) { next = sinon.spy(function (err) { if (err) { @@ -51,8 +50,8 @@ describe('middleware.source_files', function () { } beforeEach(function () { - files = helper.defer() - server = createServer(files, serveFile, '/base/path') + currentWebFiles = { included: [], served: [] } + server = createServer(currentWebFiles, serveFile, '/base/path') return server }) @@ -60,15 +59,11 @@ describe('middleware.source_files', function () { return next.resetHistory() }) - function servedFiles (list) { - return files.resolve({ included: [], served: list }) - } - describe('Range headers', function () { beforeEach(function () { - servedFiles([ + currentWebFiles.served = [ new File('/src/some.js') - ]) + ] }) it('allows single explicit ranges', function () { @@ -114,9 +109,9 @@ describe('middleware.source_files', function () { let file beforeEach(function () { file = new File('/src/some.js') - servedFiles([ + currentWebFiles.served = [ file - ]) + ] }) it('serves encoded files', function () { @@ -146,9 +141,9 @@ describe('middleware.source_files', function () { }) it('should serve absolute js source files ignoring timestamp', function () { - servedFiles([ + currentWebFiles.served = [ new File('/src/some.js') - ]) + ] return request(server) .get('/absolute/src/some.js?123345') @@ -156,9 +151,9 @@ describe('middleware.source_files', function () { }) it('should serve js source files from base folder ignoring timestamp', function () { - servedFiles([ + currentWebFiles.served = [ new File('/base/path/a.js') - ]) + ] return request(server) .get('/base/a.js?123345') @@ -169,9 +164,9 @@ describe('middleware.source_files', function () { }) it('should send strict caching headers for js source files with sha', function () { - servedFiles([ + currentWebFiles.served = [ new File('/src/some.js') - ]) + ] return request(server) .get('/absolute/src/some.js?df43b8acf136389a8dd989bda397d1c9b4e048be') @@ -183,9 +178,9 @@ describe('middleware.source_files', function () { }) it('should send strict caching headers for js source files with sha (in basePath)', function () { - servedFiles([ + currentWebFiles.served = [ new File('/base/path/a.js') - ]) + ] return request(server) .get('/base/a.js?df43b8acf136389a8dd989bda397d1c9b4e048be') @@ -196,9 +191,9 @@ describe('middleware.source_files', function () { it('should send no-caching headers for js source files without timestamps', function () { const ZERO_DATE = new RegExp(new Date(0).toUTCString()) - servedFiles([ + currentWebFiles.served = [ new File('/src/some.js') - ]) + ] return request(server) .get('/absolute/src/some.js') @@ -213,7 +208,7 @@ describe('middleware.source_files', function () { }) it('should not serve files that are not in served', function () { - servedFiles([]) + currentWebFiles.served = [] return request(server) .get('/absolute/non-existing.html') @@ -221,9 +216,9 @@ describe('middleware.source_files', function () { }) it('should serve 404 if file is served but does not exist', function () { - servedFiles([ + currentWebFiles.served = [ new File('/non-existing.js') - ]) + ] return request(server) .get('/absolute/non-existing.js') @@ -231,11 +226,11 @@ describe('middleware.source_files', function () { }) it('should serve js source file from base path containing utf8 chars', function () { - servedFiles([ + currentWebFiles.served = [ new File('/utf8ášč/some.js') - ]) + ] - server = createServer(files, serveFile, '/utf8ášč') + server = createServer(currentWebFiles, serveFile, '/utf8ášč') return request(server) .get('/base/some.js') @@ -246,11 +241,11 @@ describe('middleware.source_files', function () { }) it('should serve js source file from paths containing HTML URL encoded chars', function () { - servedFiles([ + currentWebFiles.served = [ new File('/jenkins%2Fbranch/some.js') - ]) + ] - server = createServer(files, serveFile, '') + server = createServer(currentWebFiles, serveFile, '') return request(server) .get('/base/jenkins%2Fbranch/some.js') @@ -261,9 +256,9 @@ describe('middleware.source_files', function () { }) it('should set content-type headers', function () { - servedFiles([ + currentWebFiles.served = [ new File('/base/path/index.html') - ]) + ] return request(server) .get('/base/index.html') @@ -275,9 +270,9 @@ describe('middleware.source_files', function () { const cachedFile = new File('/some/file.js') cachedFile.content = 'cached-content' - servedFiles([ + currentWebFiles.served = [ cachedFile - ]) + ] return request(server) .get('/absolute/some/file.js') @@ -292,9 +287,9 @@ describe('middleware.source_files', function () { cachedFile.content = 'cached-content' cachedFile.doNotCache = true - servedFiles([ + currentWebFiles.served = [ cachedFile - ]) + ] return request(server) .get('/absolute/src/some.js') diff --git a/test/unit/web-server.spec.js b/test/unit/web-server.spec.js index fccf57b65..31d851f53 100644 --- a/test/unit/web-server.spec.js +++ b/test/unit/web-server.spec.js @@ -34,8 +34,9 @@ describe('web-server', () => { let customFileHandlers = server = emitter = null let beforeMiddlewareActive = false let middlewareActive = false + const mockCurrentWebFiles = { served: [], included: [] } const servedFiles = (files) => { - emitter.emit('file_list_modified', { included: [], served: files }) + mockCurrentWebFiles.served = files } describe('request', () => { @@ -60,7 +61,7 @@ describe('web-server', () => { customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], - filesPromise: ['factory', m.createFilesPromise], + currentWebFiles: ['value', mockCurrentWebFiles], serveStaticFile: ['factory', m.createServeStaticFile], serveFile: ['factory', m.createServeFile], capturedBrowsers: ['value', null], @@ -228,7 +229,7 @@ describe('web-server', () => { customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], - filesPromise: ['factory', m.createFilesPromise], + currentWebFiles: ['value', mockCurrentWebFiles], serveStaticFile: ['factory', m.createServeStaticFile], serveFile: ['factory', m.createServeFile], capturedBrowsers: ['value', null], @@ -272,7 +273,7 @@ describe('web-server', () => { customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], - filesPromise: ['factory', m.createFilesPromise], + currentWebFiles: ['value', mockCurrentWebFiles], serveStaticFile: ['factory', m.createServeStaticFile], serveFile: ['factory', m.createServeFile], capturedBrowsers: ['value', null],