diff --git a/js/noms/package.json b/js/noms/package.json index 677fd4fd98..2bcbb1748c 100644 --- a/js/noms/package.json +++ b/js/noms/package.json @@ -38,6 +38,7 @@ "flow-bin": "^0.32.0", "fs-extra": "^0.30.0", "mocha": "^2.5.3", + "mock-require": "^1.3.0", "nyc": "^8.3.0" }, "scripts": { diff --git a/js/noms/src/fetch-test.js b/js/noms/src/fetch-test.js new file mode 100644 index 0000000000..f791f43201 --- /dev/null +++ b/js/noms/src/fetch-test.js @@ -0,0 +1,44 @@ +// @flow + +// Copyright 2016 Attic Labs, Inc. All rights reserved. +// Licensed under the Apache License, version 2.0: +// http://www.apache.org/licenses/LICENSE-2.0 + +import {assert} from 'chai'; +import {suite, test, setup, teardown} from 'mocha'; +import mock from 'mock-require'; + +suite('fetch', () => { + let log; + + setup(() => { + log = []; + for (const protocol of ['http', 'https']) { + mock(protocol, { + request(options) { + log.push(protocol, options.href); + return { + end() {}, + on() {}, + setTimeout() {}, + }; + }, + }); + } + }); + + teardown(() => { + mock.stopAll(); + }); + + test('http vs https', () => { + const {fetchText} = mock.reRequire('./fetch.js'); + + fetchText('http://example.com'); + assert.deepEqual(log, ['http', 'http://example.com/']); + + log = []; + fetchText('https://example.com'); + assert.deepEqual(log, ['https', 'https://example.com/']); + }); +}); diff --git a/js/noms/src/fetch.js b/js/noms/src/fetch.js index 803bb22c2c..60176bd74e 100644 --- a/js/noms/src/fetch.js +++ b/js/noms/src/fetch.js @@ -4,7 +4,8 @@ // Licensed under the Apache License, version 2.0: // http://www.apache.org/licenses/LICENSE-2.0 -import {request} from 'http'; +import * as http from 'http'; +import * as https from 'https'; import {parse} from 'url'; import * as Bytes from './bytes.js'; @@ -27,6 +28,11 @@ function objectToMap(object: {[key: string]: T}): Map { return m; } +const requestModules = { + 'http:': http, + 'https:': https, +}; + function fetch(url: string, options: FetchOptions = {}): Promise { const opts: any = parse(url); opts.method = options.method || 'GET'; @@ -34,7 +40,7 @@ function fetch(url: string, options: FetchOptions = {}): Promise { opts.headers = options.headers; } return new Promise((resolve, reject) => { - const req = request(opts, res => { + const req = requestModules[opts.protocol].request(opts, res => { if (res.statusCode < 200 || res.statusCode >= 300) { reject(new Error(`HTTP Error: ${res.statusCode}`)); return; @@ -72,7 +78,7 @@ function fetch(url: string, options: FetchOptions = {}): Promise { // then catch that event and report an error. req.setTimeout(2 * 60 * 1000, () => req.abort()); req.on('abort', () => { - reject(new Error('HTTP request timed out')); + reject(new Error('Request timed out')); }); if (options.body) {