From c0a29c22125e7f38aaf83c5d2fb58993dbd9c248 Mon Sep 17 00:00:00 2001 From: Paul Falgout Date: Fri, 3 Jan 2025 14:45:35 +0900 Subject: [PATCH 1/2] Restart closed websocket if still subscribed --- src/js/services/ws.cy.js | 47 +++++++++++++++++++++++++++++++++------- src/js/services/ws.js | 1 + 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/js/services/ws.cy.js b/src/js/services/ws.cy.js index 97f116cc8..3620ba907 100644 --- a/src/js/services/ws.cy.js +++ b/src/js/services/ws.cy.js @@ -7,8 +7,13 @@ let service; const clientKey = 'clientKey'; Cypress.Commands.add('startService', () => { + const startSpy = cy.spy().as('startService'); + + service.on('start', startSpy); + + // Return a promise that resolves when the service starts return new Cypress.Promise(resolve => { - service.on('start', resolve); + service.once('start', resolve); service.start(); }); }); @@ -80,16 +85,26 @@ context('WS Service', function() { specify('Restarting a closed socket', function() { const channel = Radio.channel('ws'); - const closedTest = { name: 'SendTest', data: 'CLOSED' }; + const closedTest = { id: 'foo', type: 'bar' }; + const addTest = { id: 'foo2', type: 'bar2' }; + + const notification = { + state: {}, + data: { + name: 'Subscribe', + data: { + clientKey: 'clientKey', + resources: [closedTest], + }, + }, + }; cy .startService() .then(() => { - cy.stub(service, 'start').as('start'); - return new Cypress.Promise(resolve => { service.ws.addEventListener('close', () => { - channel.request('send', closedTest); + channel.request('subscribe', closedTest); resolve(); }); service.ws.close(); @@ -97,9 +112,25 @@ context('WS Service', function() { }); cy - .get('@start') - .should('have.been.calledOnce') - .and('have.been.calledWith', { state: {}, data: closedTest }); + .get('@startService') + .should('be.calledTwice') + .then(spy => { + const secondCall = spy.getCall(1); + expect(secondCall.args[0]).to.deep.equal(notification); + }) + .then(() => { + channel.request('add', addTest); + service.ws.close(); + }); + + cy + .get('@startService') + .should('be.calledThrice') + .then(spy => { + const thirdCall = spy.getCall(2); + notification.data.data.resources.push(addTest); + expect(thirdCall.args[0]).to.deep.equal(notification); + }); }); specify('Message handling', function() { diff --git a/src/js/services/ws.js b/src/js/services/ws.js index 8deca21a0..656228d3a 100644 --- a/src/js/services/ws.js +++ b/src/js/services/ws.js @@ -93,6 +93,7 @@ export default App.extend({ onClose() { this.stopHeartbeat(); + if (this.resources.length) this._subscribe(); }, onMessage(event) { From 116503f2c2f79400efe8eef03503475b85d4a60d Mon Sep 17 00:00:00 2001 From: Paul Falgout Date: Sat, 4 Jan 2025 04:03:57 +0900 Subject: [PATCH 2/2] Remove destructuring merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At least in tests sometimes `_files` isn’t iterable causing the test to fail. --- src/js/entities-service/entities/actions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/entities-service/entities/actions.js b/src/js/entities-service/entities/actions.js index 3882c0aac..fc075beea 100644 --- a/src/js/entities-service/entities/actions.js +++ b/src/js/entities-service/entities/actions.js @@ -1,5 +1,5 @@ import Backbone from 'backbone'; -import { contains, extend, keys, reduce, size } from 'underscore'; +import { contains, extend, keys, reduce, size, union } from 'underscore'; import Radio from 'backbone.radio'; import Store from 'backbone.store'; import dayjs from 'dayjs'; @@ -250,7 +250,7 @@ const _Model = BaseModel.extend({ return !!size(programAction.get('allowed_uploads')); }, addFile(resource) { - const newFilesRelationship = [...this.get('_files'), { id: resource.id, type: 'files' }]; + const newFilesRelationship = union(this.get('_files'), [{ id: resource.id, type: 'files' }]); this.set({ _files: newFilesRelationship }); },