|
@@ -0,0 +1,176 @@
|
|
|
+import { afterEach, beforeEach, vi, describe, it, expect } from 'vitest'
|
|
|
+import UppySocket from './Socket.js'
|
|
|
+
|
|
|
+describe('Socket', () => {
|
|
|
+ let webSocketConstructorSpy
|
|
|
+ let webSocketCloseSpy
|
|
|
+ let webSocketSendSpy
|
|
|
+
|
|
|
+ beforeEach(() => {
|
|
|
+ webSocketConstructorSpy = vi.fn()
|
|
|
+ webSocketCloseSpy = vi.fn()
|
|
|
+ webSocketSendSpy = vi.fn()
|
|
|
+
|
|
|
+ globalThis.WebSocket = class WebSocket {
|
|
|
+ constructor (target) {
|
|
|
+ webSocketConstructorSpy(target)
|
|
|
+ }
|
|
|
+
|
|
|
+ // eslint-disable-next-line class-methods-use-this
|
|
|
+ close (args) {
|
|
|
+ webSocketCloseSpy(args)
|
|
|
+ }
|
|
|
+
|
|
|
+ // eslint-disable-next-line class-methods-use-this
|
|
|
+ send (json) {
|
|
|
+ webSocketSendSpy(json)
|
|
|
+ }
|
|
|
+
|
|
|
+ triggerOpen () {
|
|
|
+ this.onopen()
|
|
|
+ }
|
|
|
+
|
|
|
+ triggerClose () {
|
|
|
+ this.onclose()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ afterEach(() => {
|
|
|
+ globalThis.WebSocket = undefined
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should expose a class', () => {
|
|
|
+ expect(UppySocket.name).toEqual('UppySocket')
|
|
|
+ expect(
|
|
|
+ new UppySocket({
|
|
|
+ target: 'foo',
|
|
|
+ }) instanceof UppySocket,
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should setup a new WebSocket', () => {
|
|
|
+ new UppySocket({ target: 'foo' }) // eslint-disable-line no-new
|
|
|
+ expect(webSocketConstructorSpy.mock.calls[0][0]).toEqual('foo')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should send a message via the websocket if the connection is open', () => {
|
|
|
+ const uppySocket = new UppySocket({ target: 'foo' })
|
|
|
+ const webSocketInstance = uppySocket[Symbol.for('uppy test: getSocket')]()
|
|
|
+ webSocketInstance.triggerOpen()
|
|
|
+
|
|
|
+ uppySocket.send('bar', 'boo')
|
|
|
+ expect(webSocketSendSpy.mock.calls.length).toEqual(1)
|
|
|
+ expect(webSocketSendSpy.mock.calls[0]).toEqual([
|
|
|
+ JSON.stringify({ action: 'bar', payload: 'boo' }),
|
|
|
+ ])
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should queue the message for the websocket if the connection is not open', () => {
|
|
|
+ const uppySocket = new UppySocket({ target: 'foo' })
|
|
|
+
|
|
|
+ uppySocket.send('bar', 'boo')
|
|
|
+ expect(uppySocket[Symbol.for('uppy test: getQueued')]()).toEqual([{ action: 'bar', payload: 'boo' }])
|
|
|
+ expect(webSocketSendSpy.mock.calls.length).toEqual(0)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should queue any messages for the websocket if the connection is not open, then send them when the connection is open', () => {
|
|
|
+ const uppySocket = new UppySocket({ target: 'foo' })
|
|
|
+ const webSocketInstance = uppySocket[Symbol.for('uppy test: getSocket')]()
|
|
|
+
|
|
|
+ uppySocket.send('bar', 'boo')
|
|
|
+ uppySocket.send('moo', 'baa')
|
|
|
+ expect(uppySocket[Symbol.for('uppy test: getQueued')]()).toEqual([
|
|
|
+ { action: 'bar', payload: 'boo' },
|
|
|
+ { action: 'moo', payload: 'baa' },
|
|
|
+ ])
|
|
|
+ expect(webSocketSendSpy.mock.calls.length).toEqual(0)
|
|
|
+
|
|
|
+ webSocketInstance.triggerOpen()
|
|
|
+
|
|
|
+ expect(uppySocket[Symbol.for('uppy test: getQueued')]()).toEqual([])
|
|
|
+ expect(webSocketSendSpy.mock.calls.length).toEqual(2)
|
|
|
+ expect(webSocketSendSpy.mock.calls[0]).toEqual([
|
|
|
+ JSON.stringify({ action: 'bar', payload: 'boo' }),
|
|
|
+ ])
|
|
|
+ expect(webSocketSendSpy.mock.calls[1]).toEqual([
|
|
|
+ JSON.stringify({ action: 'moo', payload: 'baa' }),
|
|
|
+ ])
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should start queuing any messages when the websocket connection is closed', () => {
|
|
|
+ const uppySocket = new UppySocket({ target: 'foo' })
|
|
|
+ const webSocketInstance = uppySocket[Symbol.for('uppy test: getSocket')]()
|
|
|
+ webSocketInstance.triggerOpen()
|
|
|
+ uppySocket.send('bar', 'boo')
|
|
|
+ expect(uppySocket[Symbol.for('uppy test: getQueued')]()).toEqual([])
|
|
|
+
|
|
|
+ webSocketInstance.triggerClose()
|
|
|
+ uppySocket.send('bar', 'boo')
|
|
|
+ expect(uppySocket[Symbol.for('uppy test: getQueued')]()).toEqual([{ action: 'bar', payload: 'boo' }])
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should close the websocket when it is force closed', () => {
|
|
|
+ const uppySocket = new UppySocket({ target: 'foo' })
|
|
|
+ const webSocketInstance = uppySocket[Symbol.for('uppy test: getSocket')]()
|
|
|
+ webSocketInstance.triggerOpen()
|
|
|
+
|
|
|
+ uppySocket.close()
|
|
|
+ expect(webSocketCloseSpy.mock.calls.length).toEqual(1)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should be able to subscribe to messages received on the websocket', () => {
|
|
|
+ const uppySocket = new UppySocket({ target: 'foo' })
|
|
|
+ const webSocketInstance = uppySocket[Symbol.for('uppy test: getSocket')]()
|
|
|
+
|
|
|
+ const emitterListenerMock = vi.fn()
|
|
|
+ uppySocket.on('hi', emitterListenerMock)
|
|
|
+
|
|
|
+ webSocketInstance.triggerOpen()
|
|
|
+ webSocketInstance.onmessage({
|
|
|
+ data: JSON.stringify({ action: 'hi', payload: 'ho' }),
|
|
|
+ })
|
|
|
+ expect(emitterListenerMock.mock.calls).toEqual([
|
|
|
+ ['ho', undefined, undefined, undefined, undefined, undefined],
|
|
|
+ ])
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should be able to emit messages and subscribe to them', () => {
|
|
|
+ const uppySocket = new UppySocket({ target: 'foo' })
|
|
|
+
|
|
|
+ const emitterListenerMock = vi.fn()
|
|
|
+ uppySocket.on('hi', emitterListenerMock)
|
|
|
+
|
|
|
+ uppySocket.emit('hi', 'ho')
|
|
|
+ uppySocket.emit('hi', 'ho')
|
|
|
+ uppySocket.emit('hi', 'off to work we go')
|
|
|
+
|
|
|
+ expect(emitterListenerMock.mock.calls).toEqual([
|
|
|
+ ['ho', undefined, undefined, undefined, undefined, undefined],
|
|
|
+ ['ho', undefined, undefined, undefined, undefined, undefined],
|
|
|
+ [
|
|
|
+ 'off to work we go',
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ ],
|
|
|
+ ])
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should be able to subscribe to the first event for a particular action', () => {
|
|
|
+ const uppySocket = new UppySocket({ target: 'foo' })
|
|
|
+
|
|
|
+ const emitterListenerMock = vi.fn()
|
|
|
+ uppySocket.once('hi', emitterListenerMock)
|
|
|
+
|
|
|
+ uppySocket.emit('hi', 'ho')
|
|
|
+ uppySocket.emit('hi', 'ho')
|
|
|
+ uppySocket.emit('hi', 'off to work we go')
|
|
|
+
|
|
|
+ expect(emitterListenerMock.mock.calls.length).toEqual(1)
|
|
|
+ expect(emitterListenerMock.mock.calls).toEqual([
|
|
|
+ ['ho', undefined, undefined, undefined, undefined, undefined],
|
|
|
+ ])
|
|
|
+ })
|
|
|
+})
|