From 82a2f206dc26ae1985cdae085ba16623ae6dde9a Mon Sep 17 00:00:00 2001 From: John Cowen Date: Wed, 15 May 2019 14:59:59 +0100 Subject: [PATCH] ui: Ensure an EventSource isn't opened if closed before first tick (#5703) EventSources will wait for 1 tick before 'opening'. There is always the chance that the EventSource is '.close()'ed before that tick. We therefore check the 'readyState' before opening the EventSource --- ui-v2/app/utils/dom/event-source/callable.js | 17 +++++++++++++---- .../utils/dom/event-source/callable-test.js | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/ui-v2/app/utils/dom/event-source/callable.js b/ui-v2/app/utils/dom/event-source/callable.js index a25633c1bf..7f5fe9fe24 100644 --- a/ui-v2/app/utils/dom/event-source/callable.js +++ b/ui-v2/app/utils/dom/event-source/callable.js @@ -41,11 +41,15 @@ export default function( return P.resolve(); } : source; - this.readyState = 0; // connecting + this.readyState = 0; // CONNECTING P.resolve() .then(() => { + // if we are already closed, don't do anything + if (this.readyState !== 0) { + return; + } this.readyState = 1; // open - // ...that the connection _was just_ opened + // the connection _was just_ opened this.dispatchEvent({ type: 'open' }); return run(this, configuration, isClosed); }) @@ -63,8 +67,13 @@ export default function( } close() { // additional readyState 3 = CLOSING - if (this.readyState !== 2) { - this.readyState = 3; + switch (this.readyState) { + case 0: // CONNECTING + case 2: // CLOSED + this.readyState = 2; // CLOSED + break; + default: + this.readyState = 3; // CLOSING } } }; diff --git a/ui-v2/tests/integration/utils/dom/event-source/callable-test.js b/ui-v2/tests/integration/utils/dom/event-source/callable-test.js index 02605d6f66..14acc761ab 100644 --- a/ui-v2/tests/integration/utils/dom/event-source/callable-test.js +++ b/ui-v2/tests/integration/utils/dom/event-source/callable-test.js @@ -81,4 +81,19 @@ module('Integration | Utility | dom/event-source/callable', function(hooks) { }); }); }); + test("it can be closed before the first tick, and therefore doesn't run", function(assert) { + assert.expect(3); + const EventSource = domEventSourceCallable(EventTarget); + const listener = this.stub(); + const source = new EventSource(); + source.close(); + assert.equal(source.readyState, 2); + source.addEventListener('open', function(e) { + listener(); + }); + return Promise.resolve().then(function() { + assert.notOk(listener.called); + assert.equal(source.readyState, 2); + }); + }); });