diff --git a/test/jasmine.json b/test/jasmine.json index 057167a..2345a41 100644 --- a/test/jasmine.json +++ b/test/jasmine.json @@ -2,7 +2,8 @@ "spec_dir": "test", "spec_files": [ "spec_lib/*.js", - "spec_rule/*.js" + "spec_rule/*.js", + "spec_cli/*.js" ], "helpers": [ "../node_modules/babel-register/lib/node.js", diff --git a/test/spec_cli/anyproxy-ca_cli_spec.js b/test/spec_cli/anyproxy-ca_cli_spec.js new file mode 100644 index 0000000..5ebc6a0 --- /dev/null +++ b/test/spec_cli/anyproxy-ca_cli_spec.js @@ -0,0 +1,27 @@ +'use strict'; + +const path = require('path'); +const childProcess = require('child_process'); + +const pkg = require('../../package'); + +const binFile = path.resolve(pkg.bin['anyproxy-ca']); + +// TODO: more cases are wanted +describe('anyproxy line tool test', () => { + beforeAll(() => { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000; + }); + it('should check the ca status', done => { + childProcess.execFile(binFile, [''], (error, stdout, stderr) => { + if (error) { + console.error(error); + done.fail('anyproxy-ca failed'); + } + // If the cert is already generated, the cli will print the info, + // If the cert is not generated, the cli will prompt to install, also contains the `AnyProxy CA/ + expect(stdout).toMatch(/AnyProxy CA/); + done(); + }) + }); +}); diff --git a/test/spec_cli/anyproxy_cli_spec.js b/test/spec_cli/anyproxy_cli_spec.js new file mode 100644 index 0000000..95eec7d --- /dev/null +++ b/test/spec_cli/anyproxy_cli_spec.js @@ -0,0 +1,27 @@ +'use strict'; + +const path = require('path'); +const spawn = require('child_process').spawn; +const NoRuleSpecExec = require('../spec_rule/no_rule_spec_exec'); +const { printLog } = require('../util/CommonUtil.js'); +const pkg = require('../../package'); + +const binFile = path.resolve(pkg.bin.anyproxy); + +const startProxyFunc = function () { + printLog('Start AnyProxy by cli'); + const childProcessInstance = spawn(binFile, ['-i'], {}); + printLog('Start AnyProxy by cli successfully'); + return childProcessInstance; +} + +const closeProxyFunc = function (instance) { + printLog('Close AnyProxy in cli'); + instance.kill('SIGINT'); +} + +function testRequestByCli() { + NoRuleSpecExec(startProxyFunc, closeProxyFunc); +} + +testRequestByCli(); diff --git a/test/spec_rule/no_rule_spec.js b/test/spec_rule/no_rule_spec.js index 32373ef..c7da345 100644 --- a/test/spec_rule/no_rule_spec.js +++ b/test/spec_rule/no_rule_spec.js @@ -1,427 +1,24 @@ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; -const path = require('path'); -const fs = require('fs'); -const Server = require('../server/server.js'); -const - { - proxyGet, - proxyPost, - directGet, - directPost, - directUpload, - proxyUpload, - generateUrl, - proxyPut, - directPut, - proxyDelete, - directDelete, - directHead, - proxyHead, - directOptions, - proxyOptions, - proxyPutUpload, - directPutUpload - } = require('../util/HttpUtil.js'); -const { CommonRequestHeader } = require('../data/headers.js'); -const { isCommonResHeaderEqual, isCommonReqEqual, printLog } = require('../util/CommonUtil.js'); -const streamEqual = require('stream-equal'); - +const NoRuleSpecExec = require('./no_rule_spec_exec'); const ProxyServerUtil = require('../util/ProxyServerUtil.js'); +const { printLog } = require('../util/CommonUtil.js'); -testRequest('http'); -testRequest('https'); -testRequest('http', false); -testRequest('https', false); - -// Test suites for http and https request -function testRequest(protocol = 'http', needWeb = true) { - function constructUrl(urlPath) { - return generateUrl(protocol, urlPath); +const getStartProxyFunc = function (needWeb) { + return function () { + printLog('Start AnyProxy by node module'); + return ProxyServerUtil.defaultProxyServer(needWeb); } - - describe('Test request without proxy rules in protocol ' + protocol, () => { - let proxyServer; - let serverInstance; - - beforeAll((done) => { - jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000; - printLog('Start server for no_rule_spec'); - - serverInstance = new Server(); - proxyServer = ProxyServerUtil.defaultProxyServer(needWeb); - setTimeout(() => { - done(); - }, 2000); - }); - - afterAll(() => { - serverInstance && serverInstance.close(); - proxyServer && proxyServer.close(); - printLog('Closed server for no_rule_spec'); - }); - - - it('Get should work as direct without proxy rules', (done) => { - const url = constructUrl('/test'); - const getParam = { - param: 'nothing' - }; - - proxyGet(url, getParam, CommonRequestHeader).then((proxyRes) => { - directGet(url, getParam, CommonRequestHeader).then(directRes => { - expect(proxyRes.statusCode).toEqual(200); - expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); - expect(isCommonReqEqual(url, serverInstance)).toBe(true); - expect(proxyRes.statusCode).toEqual(directRes.statusCode); - expect(directRes.body).toEqual(proxyRes.body); - - done(); - }, error => { - console.error('error happend in direct get:', error); - done.fail('error happend in direct get'); - }); - }, error => { - console.log('error happened in proxy get:', error); - done.fail('error happend in proxy get'); - }); - }); - - it('Post should work as direct without proxy rules', (done) => { - const url = constructUrl('/test/getuser'); - const param = { - param: 'postnothing' - }; - - proxyPost(url, param, CommonRequestHeader).then(proxyRes => { - directPost(url, param, CommonRequestHeader).then(directRes => { - expect(proxyRes.statusCode).toEqual(200); - - expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); - expect(proxyRes.statusCode).toEqual(directRes.statusCode); - expect(directRes.body).toEqual(proxyRes.body); - - expect(isCommonReqEqual(url, serverInstance)).toBe(true); - - done(); - }, error => { - console.error('error in direct post:', error); - done.fail('error happend in direct post'); - }); - }, error => { - console.log('error happened in proxy post,', error); - done.fail('error happend in proxy post'); - }); - }); - - it('PUT should work as direct without proxy rules', done => { - const url = constructUrl('/test/put'); - const param = { - param: 'putsomething' - }; - proxyPut(url, param, CommonRequestHeader).then(proxyRes => { - directPut(url, param, CommonRequestHeader).then(directRes => { - expect(directRes.statusCode).toEqual(200); - - expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); - expect(directRes.statusCode).toEqual(proxyRes.statusCode); - expect(directRes.body).toEqual(proxyRes.body); - expect(isCommonReqEqual(url, serverInstance)).toBe(true); - - done(); - }, error => { - console.error('error happened in direct put', error); - done.fail('error happened in direct put'); - }); - }, error => { - console.error('error happened in proxy put', error); - done.fail('error happened in proxy put'); - }); - }); - - it('DELETE rquest should work as direct without proxy rules', (done) => { - const url = constructUrl('/test/delete/123456'); - - proxyDelete(url, {}, CommonRequestHeader).then(proxyRes => { - directDelete(url, {}, CommonRequestHeader).then(directRes => { - expect(directRes.statusCode).toEqual(200); - - expect(directRes.statusCode).toEqual(proxyRes.statusCode); - expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); - expect(directRes.body).toEqual(proxyRes.body); - expect(isCommonReqEqual(url, serverInstance)).toBe(true); - - done(); - }, error => { - console.error('error happened in direct delete :', error); - done.fail('error happened in direct delete'); - }); - }, error => { - console.error('error happened in proxy delete :', error); - done.fail('error happened in proxy delete'); - }); - }); - - it('HEAD request should work as direct without proxy rules', (done) => { - const url = constructUrl('/test/head'); - - proxyHead(url, CommonRequestHeader) - .then(proxyRes => { - directHead(url, CommonRequestHeader) - .then(directRes => { - expect(directRes.statusCode).toEqual(200); - expect(directRes.body).toEqual(''); - - expect(directRes.statusCode).toEqual(proxyRes.statusCode); - expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); - expect(directRes.body).toEqual(proxyRes.body); - expect(isCommonReqEqual(url, serverInstance)).toBe(true); - - done(); - }, error => { - console.error('error happened in direct head request:', error); - done.fail('error happened in direct head request'); - }); - }, error => { - console.error('error happened in proxy head request:', error); - done.fail('error happened in proxy head request'); - }); - }); - - it('OPTIONS request should work as direct without proxy rules', (done) => { - const url = constructUrl('/test/options'); - - proxyOptions(url, CommonRequestHeader) - .then(proxyRes => { - directOptions(url, CommonRequestHeader) - .then(directRes => { - expect(directRes.statusCode).toEqual(200); - expect(directRes.body).toEqual('could_be_empty'); - - expect(directRes.statusCode).toEqual(proxyRes.statusCode); - expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); - expect(directRes.body).toEqual(proxyRes.body); - expect(isCommonReqEqual(url, serverInstance)).toBe(true); - - done(); - }, error => { - console.error('error happened in direct options request:', error); - done.fail('error happened in direct options request'); - }); - }, error => { - console.error('error happened in proxy options request:', error); - done.fail('error happened in proxy options request'); - }); - }); - - it('304 should work as direct without proxy rules', (done) => { - const url = constructUrl('/test/response/304'); - - proxyGet(url, CommonRequestHeader) - .then(proxyRes => { - directGet(url, CommonRequestHeader) - .then(directRes => { - expect(directRes.statusCode).toEqual(304); - expect(directRes.body).toEqual(''); - - expect(directRes.statusCode).toEqual(proxyRes.statusCode); - expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); - expect(directRes.body).toEqual(proxyRes.body); - expect(isCommonReqEqual(url, serverInstance)).toBe(true); - done(); - }, error => { - console.error('error happened in direct 304 request:', error); - done.fail('error happened in direct 304 request'); - }); - }, error => { - console.error('error happened in proxy 304 request:', error); - done.fail('error happened in proxy 304 request'); - }); - }) - - describe('Response code should be honored as direct without proxy rules', () => { - [301, 302, 303].forEach(code => { - testRedirect(code); - }); - - function testRedirect(redirectCode) { - it(`${redirectCode} response should work as direct without proxy rules`, (done) => { - const url = constructUrl(`/test/response/${redirectCode}`); - - proxyGet(url) - .then(proxyRes => { - directGet(url) - .then(directRes => { - expect(directRes.statusCode).toEqual(redirectCode); - expect(directRes.headers.location).toEqual(proxyRes.headers.location); - expect(directRes.statusCode).toEqual(proxyRes.statusCode); - expect(directRes.headers.location).toEqual('/test'); - done(); - }).catch(error => { - console.log(`error happened in direct ${redirectCode}:`, error); - done.fail(`error happened in direct ${redirectCode}`); - }); - }).catch(error => { - console.log(`error happened in proxy ${redirectCode}:`, error); - done.fail(`error happened in proxy ${redirectCode}`); - }); - }); - } - }); - - describe('Test file download ', () => { - const testArray = [ - { - url: constructUrl('/test/download/png'), - type: 'png', - contentType: 'image/png' - }, - { - url: constructUrl('/test/download/webp'), - type: 'WEBP', - contentType: 'image/webp' - }, - { - url: constructUrl('/test/download/json'), - type: 'JSON', - contentType: 'application/json; charset=utf-8' - }, - { - url: constructUrl('/test/download/css'), - type: 'CSS', - contentType: 'text/css; charset=utf-8' - }, - { - url: constructUrl('/test/download/ttf'), - type: 'TTF', - contentType: 'application/x-font-ttf' - }, - { - url: constructUrl('/test/download/eot'), - type: 'EOT', - contentType: 'application/vnd.ms-fontobject' - }, - { - url: constructUrl('/test/download/svg'), - type: 'SVG', - contentType: 'image/svg+xml' - }, - { - url: constructUrl('/test/download/woff'), - type: 'WOFF', - contentType: 'application/font-woff' - }, - { - url: constructUrl('/test/download/woff2'), - type: 'WOFF2', - contentType: 'application/font-woff2' - } - ]; - - testArray.forEach(item => { - testFileDownload(item.url, item.type, item.contentType); - }); - - // 封装测试文件下载的测试工具类 - function testFileDownload(url, filetype, contentType) { - const describe = `${filetype} file download without rules should be work as direct download`; - const param = {}; - - it(describe, (done) => { - proxyGet(url, param).then(proxyRes => { - directGet(url, param).then(directRes => { - expect(proxyRes.statusCode).toEqual(200); - - expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); - expect(proxyRes.statusCode).toEqual(directRes.statusCode); - expect(proxyRes.body).toEqual(directRes.body); - expect(isCommonReqEqual(url, serverInstance)).toBe(true); - done(); - }, error => { - console.error('error in direct get :', filetype, error); - done.fail(`error happend in direct get ${filetype}`); - }); - }, error => { - console.error('error in proxy get :', filetype, error); - done.fail(`error happend in proxy get ${filetype}`); - }); - }); - } - }); - - describe('Test file upload', () => { - const formParams = { - param1: 'param_1', - param2: 'param2' - }; - it('POST upload should be working', (done) => { - const url = constructUrl('/test/upload/png'); - const filePath = path.resolve(__dirname, '../data/test.png'); - - proxyUpload(url, filePath, formParams) - .then(proxyRes => { - directUpload(url, filePath, formParams) - .then((directRes) => { - expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); - expect(isCommonReqEqual(url, serverInstance)).toBe(true); - assertReponse(proxyRes, directRes, filePath, done); - }, error => { - console.error('error in direct upload:', error); - done.fail('error in direct upload'); - }); - }, error => { - console.error('error in proxy upload:', error); - done.fail('error in proxy upload:'); - }); - }); - - it('PUT upload should be working', (done) => { - const url = constructUrl('/test/upload/putpng'); - const filePath = path.resolve(__dirname, '../data/test.png'); - proxyPutUpload(url, filePath, formParams) - .then(proxyRes => { - directPutUpload(url, filePath, formParams) - .then((directRes) => { - expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); - - assertReponse(proxyRes, directRes, filePath, done); - }, error => { - console.error('error in direct upload:', error); - done.fail('error in direct upload'); - }); - }, error => { - console.error('error in proxy upload:', error); - done.fail('error in proxy upload:'); - }); - }); - - function assertReponse(proxyRes, directRes, originFilePath, done) { - expect(proxyRes.statusCode).toEqual(200); - - expect(proxyRes.statusCode).toEqual(directRes.statusCode); - // expect(proxyRes.headers.reqbody).toEqual(directRes.headers.reqbody); - - // the body will be the file path - const directUploadedStream = fs.createReadStream(directRes.body); - const proxyUploadedStream = fs.createReadStream(proxyRes.body); - const localFileStream = fs.createReadStream(originFilePath); - streamEqual(directUploadedStream, localFileStream) - .then(isLocalEqual => { - expect(isLocalEqual).toBe(true); - streamEqual(directUploadedStream, proxyUploadedStream) - .then(isUploadedEqual => { - expect(isUploadedEqual).toBe(true); - done(); - }, error => { - console.error('error in comparing directUpload with proxy:\n', error); - done.fail('error in comparing directUpload with proxy'); - }); - done(); - }, error => { - console.error('error in comparing directUpload with local:\n', error); - done.fail('error in comparing directUpload with local'); - }); - } - }); - }); +} + +const closeProxyFunc = function (instance) { + printLog('Close AnyProxy by node module'); + instance.close(); +} + +testRequest(); +testRequest(false); + +function testRequest(needWeb = true) { + NoRuleSpecExec(getStartProxyFunc(needWeb), closeProxyFunc); } diff --git a/test/spec_rule/no_rule_spec_exec.js b/test/spec_rule/no_rule_spec_exec.js new file mode 100644 index 0000000..4d94e26 --- /dev/null +++ b/test/spec_rule/no_rule_spec_exec.js @@ -0,0 +1,430 @@ + +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; +const path = require('path'); +const fs = require('fs'); +const Server = require('../server/server.js'); +const + { + proxyGet, + proxyPost, + directGet, + directPost, + directUpload, + proxyUpload, + generateUrl, + proxyPut, + directPut, + proxyDelete, + directDelete, + directHead, + proxyHead, + directOptions, + proxyOptions, + proxyPutUpload, + directPutUpload + } = require('../util/HttpUtil.js'); +const { CommonRequestHeader } = require('../data/headers.js'); +const { isCommonResHeaderEqual, isCommonReqEqual, printLog } = require('../util/CommonUtil.js'); +const streamEqual = require('stream-equal'); + +/** + * + * @param {String} protocol the protocol to test + * @param {Function} proxyStartFunc the function to start an AnyProxy + * @param {Function} proxyCloseFunc the function to close the AnyProxy instance + */ +function testRequest(protocol = 'http', proxyStartFunc, proxyCloseFunc) { + function constructUrl(urlPath) { + return generateUrl(protocol, urlPath); + } + + describe('Test request without proxy rules in protocol ' + protocol, () => { + let proxyServer; + let serverInstance; + + beforeAll((done) => { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000; + printLog('Start server for no_rule_spec'); + + serverInstance = new Server(); + proxyServer = proxyStartFunc(); + setTimeout(() => { + done(); + }, 2000); + }); + + afterAll(() => { + serverInstance && serverInstance.close(); + proxyCloseFunc(proxyServer); + printLog('Closed server for no_rule_spec'); + }); + + + it('Get should work as direct without proxy rules', (done) => { + const url = constructUrl('/test'); + const getParam = { + param: 'nothing' + }; + + proxyGet(url, getParam, CommonRequestHeader).then((proxyRes) => { + directGet(url, getParam, CommonRequestHeader).then(directRes => { + expect(proxyRes.statusCode).toEqual(200); + expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); + expect(isCommonReqEqual(url, serverInstance)).toBe(true); + expect(proxyRes.statusCode).toEqual(directRes.statusCode); + expect(directRes.body).toEqual(proxyRes.body); + + done(); + }, error => { + console.error('error happend in direct get:', error); + done.fail('error happend in direct get'); + }); + }, error => { + console.log('error happened in proxy get:', error); + done.fail('error happend in proxy get'); + }); + }); + + it('Post should work as direct without proxy rules', (done) => { + const url = constructUrl('/test/getuser'); + const param = { + param: 'postnothing' + }; + + proxyPost(url, param, CommonRequestHeader).then(proxyRes => { + directPost(url, param, CommonRequestHeader).then(directRes => { + expect(proxyRes.statusCode).toEqual(200); + + expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); + expect(proxyRes.statusCode).toEqual(directRes.statusCode); + expect(directRes.body).toEqual(proxyRes.body); + + expect(isCommonReqEqual(url, serverInstance)).toBe(true); + + done(); + }, error => { + console.error('error in direct post:', error); + done.fail('error happend in direct post'); + }); + }, error => { + console.log('error happened in proxy post,', error); + done.fail('error happend in proxy post'); + }); + }); + + it('PUT should work as direct without proxy rules', done => { + const url = constructUrl('/test/put'); + const param = { + param: 'putsomething' + }; + proxyPut(url, param, CommonRequestHeader).then(proxyRes => { + directPut(url, param, CommonRequestHeader).then(directRes => { + expect(directRes.statusCode).toEqual(200); + + expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); + expect(directRes.statusCode).toEqual(proxyRes.statusCode); + expect(directRes.body).toEqual(proxyRes.body); + expect(isCommonReqEqual(url, serverInstance)).toBe(true); + + done(); + }, error => { + console.error('error happened in direct put', error); + done.fail('error happened in direct put'); + }); + }, error => { + console.error('error happened in proxy put', error); + done.fail('error happened in proxy put'); + }); + }); + + it('DELETE rquest should work as direct without proxy rules', (done) => { + const url = constructUrl('/test/delete/123456'); + + proxyDelete(url, {}, CommonRequestHeader).then(proxyRes => { + directDelete(url, {}, CommonRequestHeader).then(directRes => { + expect(directRes.statusCode).toEqual(200); + + expect(directRes.statusCode).toEqual(proxyRes.statusCode); + expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); + expect(directRes.body).toEqual(proxyRes.body); + expect(isCommonReqEqual(url, serverInstance)).toBe(true); + + done(); + }, error => { + console.error('error happened in direct delete :', error); + done.fail('error happened in direct delete'); + }); + }, error => { + console.error('error happened in proxy delete :', error); + done.fail('error happened in proxy delete'); + }); + }); + + it('HEAD request should work as direct without proxy rules', (done) => { + const url = constructUrl('/test/head'); + + proxyHead(url, CommonRequestHeader) + .then(proxyRes => { + directHead(url, CommonRequestHeader) + .then(directRes => { + expect(directRes.statusCode).toEqual(200); + expect(directRes.body).toEqual(''); + + expect(directRes.statusCode).toEqual(proxyRes.statusCode); + expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); + expect(directRes.body).toEqual(proxyRes.body); + expect(isCommonReqEqual(url, serverInstance)).toBe(true); + + done(); + }, error => { + console.error('error happened in direct head request:', error); + done.fail('error happened in direct head request'); + }); + }, error => { + console.error('error happened in proxy head request:', error); + done.fail('error happened in proxy head request'); + }); + }); + + it('OPTIONS request should work as direct without proxy rules', (done) => { + const url = constructUrl('/test/options'); + + proxyOptions(url, CommonRequestHeader) + .then(proxyRes => { + directOptions(url, CommonRequestHeader) + .then(directRes => { + expect(directRes.statusCode).toEqual(200); + expect(directRes.body).toEqual('could_be_empty'); + + expect(directRes.statusCode).toEqual(proxyRes.statusCode); + expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); + expect(directRes.body).toEqual(proxyRes.body); + expect(isCommonReqEqual(url, serverInstance)).toBe(true); + + done(); + }, error => { + console.error('error happened in direct options request:', error); + done.fail('error happened in direct options request'); + }); + }, error => { + console.error('error happened in proxy options request:', error); + done.fail('error happened in proxy options request'); + }); + }); + + it('304 should work as direct without proxy rules', (done) => { + const url = constructUrl('/test/response/304'); + + proxyGet(url, CommonRequestHeader) + .then(proxyRes => { + directGet(url, CommonRequestHeader) + .then(directRes => { + expect(directRes.statusCode).toEqual(304); + expect(directRes.body).toEqual(''); + + expect(directRes.statusCode).toEqual(proxyRes.statusCode); + expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); + expect(directRes.body).toEqual(proxyRes.body); + expect(isCommonReqEqual(url, serverInstance)).toBe(true); + done(); + }, error => { + console.error('error happened in direct 304 request:', error); + done.fail('error happened in direct 304 request'); + }); + }, error => { + console.error('error happened in proxy 304 request:', error); + done.fail('error happened in proxy 304 request'); + }); + }) + + describe('Response code should be honored as direct without proxy rules', () => { + [301, 302, 303].forEach(code => { + testRedirect(code); + }); + + function testRedirect(redirectCode) { + it(`${redirectCode} response should work as direct without proxy rules`, (done) => { + const url = constructUrl(`/test/response/${redirectCode}`); + + proxyGet(url) + .then(proxyRes => { + directGet(url) + .then(directRes => { + expect(directRes.statusCode).toEqual(redirectCode); + expect(directRes.headers.location).toEqual(proxyRes.headers.location); + expect(directRes.statusCode).toEqual(proxyRes.statusCode); + expect(directRes.headers.location).toEqual('/test'); + done(); + }).catch(error => { + console.log(`error happened in direct ${redirectCode}:`, error); + done.fail(`error happened in direct ${redirectCode}`); + }); + }).catch(error => { + console.log(`error happened in proxy ${redirectCode}:`, error); + done.fail(`error happened in proxy ${redirectCode}`); + }); + }); + } + }); + + describe('Test file download ', () => { + const testArray = [ + { + url: constructUrl('/test/download/png'), + type: 'png', + contentType: 'image/png' + }, + { + url: constructUrl('/test/download/webp'), + type: 'WEBP', + contentType: 'image/webp' + }, + { + url: constructUrl('/test/download/json'), + type: 'JSON', + contentType: 'application/json; charset=utf-8' + }, + { + url: constructUrl('/test/download/css'), + type: 'CSS', + contentType: 'text/css; charset=utf-8' + }, + { + url: constructUrl('/test/download/ttf'), + type: 'TTF', + contentType: 'application/x-font-ttf' + }, + { + url: constructUrl('/test/download/eot'), + type: 'EOT', + contentType: 'application/vnd.ms-fontobject' + }, + { + url: constructUrl('/test/download/svg'), + type: 'SVG', + contentType: 'image/svg+xml' + }, + { + url: constructUrl('/test/download/woff'), + type: 'WOFF', + contentType: 'application/font-woff' + }, + { + url: constructUrl('/test/download/woff2'), + type: 'WOFF2', + contentType: 'application/font-woff2' + } + ]; + + testArray.forEach(item => { + testFileDownload(item.url, item.type, item.contentType); + }); + + // 封装测试文件下载的测试工具类 + function testFileDownload(url, filetype, contentType) { + const describe = `${filetype} file download without rules should be work as direct download`; + const param = {}; + + it(describe, (done) => { + proxyGet(url, param).then(proxyRes => { + directGet(url, param).then(directRes => { + expect(proxyRes.statusCode).toEqual(200); + + expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); + expect(proxyRes.statusCode).toEqual(directRes.statusCode); + expect(proxyRes.body).toEqual(directRes.body); + expect(isCommonReqEqual(url, serverInstance)).toBe(true); + done(); + }, error => { + console.error('error in direct get :', filetype, error); + done.fail(`error happend in direct get ${filetype}`); + }); + }, error => { + console.error('error in proxy get :', filetype, error); + done.fail(`error happend in proxy get ${filetype}`); + }); + }); + } + }); + + describe('Test file upload', () => { + const formParams = { + param1: 'param_1', + param2: 'param2' + }; + it('POST upload should be working', (done) => { + const url = constructUrl('/test/upload/png'); + const filePath = path.resolve(__dirname, '../data/test.png'); + + proxyUpload(url, filePath, formParams) + .then(proxyRes => { + directUpload(url, filePath, formParams) + .then((directRes) => { + expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); + expect(isCommonReqEqual(url, serverInstance)).toBe(true); + assertReponse(proxyRes, directRes, filePath, done); + }, error => { + console.error('error in direct upload:', error); + done.fail('error in direct upload'); + }); + }, error => { + console.error('error in proxy upload:', error); + done.fail('error in proxy upload:'); + }); + }); + + it('PUT upload should be working', (done) => { + const url = constructUrl('/test/upload/putpng'); + const filePath = path.resolve(__dirname, '../data/test.png'); + proxyPutUpload(url, filePath, formParams) + .then(proxyRes => { + directPutUpload(url, filePath, formParams) + .then((directRes) => { + expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true); + + assertReponse(proxyRes, directRes, filePath, done); + }, error => { + console.error('error in direct upload:', error); + done.fail('error in direct upload'); + }); + }, error => { + console.error('error in proxy upload:', error); + done.fail('error in proxy upload:'); + }); + }); + + function assertReponse(proxyRes, directRes, originFilePath, done) { + expect(proxyRes.statusCode).toEqual(200); + + expect(proxyRes.statusCode).toEqual(directRes.statusCode); + // expect(proxyRes.headers.reqbody).toEqual(directRes.headers.reqbody); + + // the body will be the file path + const directUploadedStream = fs.createReadStream(directRes.body); + const proxyUploadedStream = fs.createReadStream(proxyRes.body); + const localFileStream = fs.createReadStream(originFilePath); + streamEqual(directUploadedStream, localFileStream) + .then(isLocalEqual => { + expect(isLocalEqual).toBe(true); + streamEqual(directUploadedStream, proxyUploadedStream) + .then(isUploadedEqual => { + expect(isUploadedEqual).toBe(true); + done(); + }, error => { + console.error('error in comparing directUpload with proxy:\n', error); + done.fail('error in comparing directUpload with proxy'); + }); + done(); + }, error => { + console.error('error in comparing directUpload with local:\n', error); + done.fail('error in comparing directUpload with local'); + }); + } + }); + }); +} + +module.exports = function (startProxyFunc, closeProxyFunc) { + testRequest('http', startProxyFunc, closeProxyFunc); + testRequest('https', startProxyFunc, closeProxyFunc); +};