diff --git a/packages/net-stubbing/lib/server/util.ts b/packages/net-stubbing/lib/server/util.ts index c33d4be1464f..306766cdae84 100644 --- a/packages/net-stubbing/lib/server/util.ts +++ b/packages/net-stubbing/lib/server/util.ts @@ -1,5 +1,6 @@ import _ from 'lodash' import Debug from 'debug' +import mime from 'mime' import isHtml from 'is-html' import { IncomingMessage } from 'http' import { @@ -18,12 +19,39 @@ import type { CypressIncomingRequest } from '@packages/proxy' import type { InterceptedRequest } from './intercepted-request' import { caseInsensitiveGet, caseInsensitiveHas } from '../util' -// TODO: move this into net-stubbing once cy.route is removed -import { parseContentType } from '@packages/server/lib/controllers/xhrs' import type { CyHttpMessages } from '../external-types' import { getEncoding } from 'istextorbinary' const debug = Debug('cypress:net-stubbing:server:util') +const htmlLikeRe = /<.+>[\s\S]+<\/.+>/ + +const isValidJSON = function (text: unknown) { + if (_.isObject(text)) { + return true + } + + try { + const o = JSON.parse(text as string) + + return _.isObject(o) + } catch (error) { + false + } + + return false +} + +export function parseContentType (response?: string) { + if (isValidJSON(response)) { + return mime.getType('json') + } + + if (response && htmlLikeRe.test(response)) { + return mime.getType('html') + } + + return mime.getType('text') +} export function emit (socket: CyServer.Socket, eventName: string, data: object) { if (debug.enabled) { diff --git a/packages/net-stubbing/package.json b/packages/net-stubbing/package.json index 50c70f84570a..70b97b525460 100644 --- a/packages/net-stubbing/package.json +++ b/packages/net-stubbing/package.json @@ -16,6 +16,7 @@ "is-html": "^2.0.0", "istextorbinary": "6.0.0", "lodash": "^4.17.15", + "mime": "^2.6.0", "mime-types": "2.1.27", "minimatch": "^3.1.2", "throttle": "^1.0.3" diff --git a/packages/net-stubbing/test/unit/util-spec.ts b/packages/net-stubbing/test/unit/util-spec.ts index 3775f48ffa8d..440b638d67e0 100644 --- a/packages/net-stubbing/test/unit/util-spec.ts +++ b/packages/net-stubbing/test/unit/util-spec.ts @@ -1,4 +1,4 @@ -import { getBodyEncoding } from '../../lib/server/util' +import { getBodyEncoding, parseContentType } from '../../lib/server/util' import { expect } from 'chai' import { join } from 'path' import { readFileSync } from 'fs' @@ -6,6 +6,34 @@ import { readFileSync } from 'fs' const imageBuffer = readFileSync(join(__dirname, '..', 'fixtures', 'cypress-logo.png')) describe('net-stubbing util', () => { + describe('parseContentType', () => { + it('returns application/json', () => { + const str = JSON.stringify({ foo: 'bar' }) + + expect(parseContentType(str)).to.eq('application/json') + }) + + it('returns text/html', () => { + const str = `\ + +
foobarbaz +\ +` + + expect(parseContentType(str)).to.eq('text/html') + }) + + it('returns text/plain', () => { + const str = 'foobarbaz' + + expect(parseContentType(str)).to.eq('text/plain') + }) + + it('returns text/plain by default', () => { + expect(parseContentType()).to.eq('text/plain') + }) + }) + context('getBodyEncoding', () => { it('returns null without data', () => { expect(getBodyEncoding(null)).to.equal(null) diff --git a/packages/server/lib/controllers/xhrs.js b/packages/server/lib/controllers/xhrs.ts similarity index 71% rename from packages/server/lib/controllers/xhrs.js rename to packages/server/lib/controllers/xhrs.ts index 092786bd4db3..d0716a728017 100644 --- a/packages/server/lib/controllers/xhrs.js +++ b/packages/server/lib/controllers/xhrs.ts @@ -1,30 +1,13 @@ -const _ = require('lodash') -const mime = require('mime') -const Promise = require('bluebird') -const fixture = require('../fixture') +import { parseContentType } from '@packages/net-stubbing/lib/server/util' +import _ from 'lodash' +import Promise from 'bluebird' +import fixture from '../fixture' const fixturesRe = /^(fx:|fixture:)/ -const htmlLikeRe = /<.+>[\s\S]+<\/.+>/ -const isValidJSON = function (text) { - if (_.isObject(text)) { - return true - } - - try { - const o = JSON.parse(text) - - return _.isObject(o) - } catch (error) { - false - } - - return false -} - -module.exports = { +export = { handle (req, res, config, next) { - const get = function (val, def) { + const get = function (val, def?) { return decodeURI(req.get(val) || def) } @@ -37,7 +20,7 @@ module.exports = { // figure out the stream interface and pipe these // chunks to the response return this.getResponse(response, config) - .then((resp = {}) => { + .then((resp: { data: any, encoding?: BufferEncoding }) => { let { data, encoding } = resp // grab content-type from x-cypress-headers if present @@ -73,7 +56,7 @@ module.exports = { .set(headers) .status(status) .end(chunk) - }).catch((err) => { + }).catch((err: Error) => { return res .status(400) .send({ __error: err.stack }) @@ -87,8 +70,8 @@ module.exports = { return respond() }, - _get (resp, config) { - const options = {} + _get (resp: string, config: { fixturesFolder: string }): Promise<{ data: any, encoding?: string }> { + const options: { encoding?: string } = {} const file = resp.replace(fixturesRe, '') @@ -99,7 +82,7 @@ module.exports = { } return fixture.get(config.fixturesFolder, filePath, options) - .then((bytes) => { + .then((bytes: any) => { return { data: bytes, encoding, @@ -115,22 +98,6 @@ module.exports = { return Promise.resolve({ data: resp }) }, - parseContentType (response) { - const ret = (type) => { - return mime.getType(type) //+ "; charset=utf-8" - } - - if (isValidJSON(response)) { - return ret('json') - } - - if (htmlLikeRe.test(response)) { - return ret('html') - } - - return ret('text') - }, - parseHeaders (headers, response) { try { headers = JSON.parse(headers) @@ -141,7 +108,7 @@ module.exports = { } if (headers['content-type'] == null) { - headers['content-type'] = this.parseContentType(response) + headers['content-type'] = parseContentType(response) } return headers diff --git a/packages/server/test/unit/xhrs_spec.js b/packages/server/test/unit/xhrs_spec.js index 1ec71fc6fa80..d981a947596e 100644 --- a/packages/server/test/unit/xhrs_spec.js +++ b/packages/server/test/unit/xhrs_spec.js @@ -3,34 +3,6 @@ require('../spec_helper') const xhrs = require(`../../lib/controllers/xhrs`) describe('lib/controllers/xhr', () => { - describe('#parseContentType', () => { - it('returns application/json', () => { - const str = JSON.stringify({ foo: 'bar' }) - - expect(xhrs.parseContentType(str)).to.eq('application/json') - }) - - it('returns text/html', () => { - const str = `\ - -
foobarbaz -\ -` - - expect(xhrs.parseContentType(str)).to.eq('text/html') - }) - - it('returns text/plain', () => { - const str = 'foobarbaz' - - expect(xhrs.parseContentType(str)).to.eq('text/plain') - }) - - it('returns text/plain by default', () => { - expect(xhrs.parseContentType()).to.eq('text/plain') - }) - }) - describe('#parseHeaders', () => { it('returns object literal on undefined', () => { const obj = xhrs.parseHeaders(undefined) diff --git a/yarn.lock b/yarn.lock index 6d5047cf9583..efab20329721 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22392,7 +22392,7 @@ mime@1.6.0, mime@^1.3.4, mime@^1.4.1, mime@^1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@2.6.0, mime@^2.4.6, mime@^2.5.2: +mime@2.6.0, mime@^2.4.6, mime@^2.5.2, mime@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==