From db67432468a358e747a3e1146080c5319b550fd7 Mon Sep 17 00:00:00 2001 From: Jovan Gerodetti Date: Fri, 15 Jun 2018 23:51:52 +0200 Subject: [PATCH] [NetworkRequest] make requests cancellable #46 (#56) * only call the xhr abort if the request has been sent * test request constructor to get at least a bit of coverage --- core/NetworkRequest.js | 20 ++++++++++++++++++++ tests/NetworkRequest.js | 21 +++++++++++++++++++++ tests/main.js | 4 +--- tests/testTasks/NetworkRequest/construct.js | 3 +++ 4 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 tests/NetworkRequest.js create mode 100644 tests/testTasks/NetworkRequest/construct.js diff --git a/core/NetworkRequest.js b/core/NetworkRequest.js index 586e19f..4cc34e5 100644 --- a/core/NetworkRequest.js +++ b/core/NetworkRequest.js @@ -27,6 +27,8 @@ const stripHashKey = function(object) { return object; }; +const xhrMap = new WeakMap(); + /** * A network request */ @@ -71,6 +73,9 @@ const NetworkRequest = { */ completed: false, + /** @type {Promise} */ + promise: null, + /** * The constructor for the NetworkRequest. It simply sets up the properties. * @@ -159,6 +164,8 @@ const NetworkRequest = { send() { const xhr = new XMLHttpRequest(); + xhrMap.set(this, xhr); + if (this.method === 'GET' && this._body) { this.url += `?${ Object.keys(this._body).map((key) => { return `${key}=${this._body[key]}`; @@ -211,9 +218,22 @@ const NetworkRequest = { xhr.send(this._body); } + this.promise = promise; + return promise; }, + cancel() { + /** @type {XMLHttpRequest} */ + const xhr = xhrMap.get(this); + + if (!xhr) { + return; + } + + return xhr.abort(); + }, + __proto__: EventTarget, }; diff --git a/tests/NetworkRequest.js b/tests/NetworkRequest.js new file mode 100644 index 0000000..3b6352d --- /dev/null +++ b/tests/NetworkRequest.js @@ -0,0 +1,21 @@ +/* eslint-env mocha */ + +const istanbulVM = require('../testable/node/istanbulVM'); +const expect = require('chai').expect; + + +describe('NetworkRequest', () => { + const vm = istanbulVM(); + + istanbulVM.applyNodeEnv(vm); + + vm.runModule('../testable/core/NetworkRequest'); + + it('should construct a new request', () => { + const result = vm.runModule('./testTasks/NetworkRequest/construct'); + + expect(result.instance.url).to.equal('https://example.org'); + expect(result.instance.method).to.equal('POST'); + expect(result.instance.type).to.equal('json'); + }); +}); diff --git a/tests/main.js b/tests/main.js index 78ce02b..8462466 100755 --- a/tests/main.js +++ b/tests/main.js @@ -59,9 +59,7 @@ describe('Prototypes', () => { require('./EventTarget.js'); require('./Catalog'); - describe('NetworkReqest', () => { - Import('../../testable/core/NetworkRequest'); - }); + require('./NetworkRequest'); }); describe('ServiceWorker', () => { diff --git a/tests/testTasks/NetworkRequest/construct.js b/tests/testTasks/NetworkRequest/construct.js new file mode 100644 index 0000000..17020a6 --- /dev/null +++ b/tests/testTasks/NetworkRequest/construct.js @@ -0,0 +1,3 @@ +/* global NetworkRequest */ +global.NetworkRequest = NetworkRequest; +global.instance = Object.create(NetworkRequest).constructor('https://example.org', { method: 'POST', type: 'json' });