202 lines
5.2 KiB
TypeScript
202 lines
5.2 KiB
TypeScript
jest.mock('simple-peer')
|
|
jest.mock('../window')
|
|
|
|
import * as SocketActions from './SocketActions'
|
|
import * as constants from '../constants'
|
|
import Peer from 'simple-peer'
|
|
import { EventEmitter } from 'events'
|
|
import { createStore, Store, GetState } from '../store'
|
|
import { ClientSocket } from '../socket'
|
|
import { Dispatch } from 'redux'
|
|
import { MediaStream } from '../window'
|
|
import { SocketEvent } from '../../shared'
|
|
|
|
describe('SocketActions', () => {
|
|
const roomName = 'bla'
|
|
|
|
let socket: ClientSocket
|
|
let store: Store
|
|
let dispatch: Dispatch
|
|
let getState: GetState
|
|
let instances: Peer.Instance[]
|
|
beforeEach(() => {
|
|
socket = new EventEmitter() as any;
|
|
(socket as any).id = 'a'
|
|
|
|
store = createStore()
|
|
getState = store.getState
|
|
dispatch = store.dispatch
|
|
|
|
instances = (Peer as any).instances = []
|
|
})
|
|
|
|
const userA = {
|
|
socketId: 'socket-a',
|
|
userId: 'user-a',
|
|
}
|
|
const userId = userA.userId
|
|
|
|
const userB = {
|
|
socketId: 'socket-b',
|
|
userId: 'user-b',
|
|
}
|
|
|
|
const userC = {
|
|
socketId: 'socket-c',
|
|
userId: 'user-c',
|
|
}
|
|
|
|
describe('handshake', () => {
|
|
describe('users', () => {
|
|
beforeEach(() => {
|
|
SocketActions
|
|
.handshake({ socket, roomName, userId })(dispatch, getState)
|
|
const payload = {
|
|
users: [userA, userB],
|
|
initiator: userA.userId,
|
|
}
|
|
socket.emit('users', payload)
|
|
expect(instances.length).toBe(1)
|
|
})
|
|
|
|
it('adds a peer for each new user and keeps active connections', () => {
|
|
const payload = {
|
|
users: [userA, userC],
|
|
initiator: userC.userId,
|
|
}
|
|
socket.emit(constants.SOCKET_EVENT_USERS, payload)
|
|
|
|
// then
|
|
expect(instances.length).toBe(2)
|
|
expect((instances[0].destroy as jest.Mock).mock.calls.length).toBe(0)
|
|
expect((instances[1].destroy as jest.Mock).mock.calls.length).toBe(0)
|
|
})
|
|
})
|
|
|
|
describe('signal', () => {
|
|
let data: Peer.SignalData
|
|
beforeEach(() => {
|
|
data = {} as any
|
|
SocketActions
|
|
.handshake({ socket, roomName, userId })(dispatch, getState)
|
|
socket.emit('users', {
|
|
initiator: userA.userId,
|
|
users: [userA, userB],
|
|
})
|
|
})
|
|
|
|
it('should forward signal to peer', () => {
|
|
socket.emit('signal', {
|
|
userId: userB.userId,
|
|
signal: data,
|
|
})
|
|
|
|
expect(instances.length).toBe(1)
|
|
expect((instances[0].signal as jest.Mock).mock.calls.length).toBe(1)
|
|
})
|
|
|
|
it('does nothing if no peer', () => {
|
|
socket.emit('signal', {
|
|
userId: 'a',
|
|
signal: data,
|
|
})
|
|
|
|
expect(instances.length).toBe(1)
|
|
expect((instances[0].signal as jest.Mock).mock.calls.length).toBe(0)
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('peer events', () => {
|
|
let peer: Peer.Instance
|
|
beforeEach(() => {
|
|
let ready = false
|
|
socket.once('ready', () => { ready = true })
|
|
|
|
SocketActions
|
|
.handshake({ socket, roomName, userId })(dispatch, getState)
|
|
|
|
socket.emit('users', {
|
|
initiator: userA.userId,
|
|
users: [userA, userB],
|
|
})
|
|
expect(instances.length).toBe(1)
|
|
peer = instances[0]
|
|
|
|
expect(ready).toBeDefined()
|
|
})
|
|
|
|
describe('error', () => {
|
|
it('destroys peer', () => {
|
|
peer.emit(constants.PEER_EVENT_ERROR, new Error('bla'))
|
|
expect((peer.destroy as jest.Mock).mock.calls.length).toBe(1)
|
|
})
|
|
})
|
|
|
|
describe('signal', () => {
|
|
it('emits socket signal with user id', done => {
|
|
const signal = { bla: 'bla' }
|
|
|
|
socket.once('signal', (payload: SocketEvent['signal']) => {
|
|
expect(payload.userId).toEqual(userB.userId)
|
|
expect(payload.signal).toBe(signal)
|
|
done()
|
|
})
|
|
|
|
peer.emit('signal', signal)
|
|
})
|
|
})
|
|
|
|
describe('stream', () => {
|
|
it('adds a stream to streamStore', () => {
|
|
const stream = {
|
|
getTracks() {
|
|
return [{
|
|
stop: jest.fn(),
|
|
}]
|
|
},
|
|
}
|
|
peer.emit(constants.PEER_EVENT_TRACK, stream.getTracks()[0], stream)
|
|
|
|
expect(store.getState().streams).toEqual({
|
|
[userB.userId]: {
|
|
userId: userB.userId,
|
|
streams: [{
|
|
stream,
|
|
type: undefined,
|
|
url: jasmine.any(String),
|
|
}],
|
|
},
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('close', () => {
|
|
beforeEach(() => {
|
|
const stream = new MediaStream()
|
|
const track = {} as unknown as MediaStreamTrack
|
|
peer.emit(constants.PEER_EVENT_TRACK, track, stream)
|
|
// test stream with two tracks
|
|
peer.emit(constants.PEER_EVENT_TRACK, track, stream)
|
|
expect(store.getState().streams).toEqual({
|
|
[userB.userId]: {
|
|
userId: userB.userId,
|
|
streams: [{
|
|
stream,
|
|
type: undefined,
|
|
url: jasmine.any(String),
|
|
}],
|
|
},
|
|
})
|
|
})
|
|
|
|
it('removes stream & peer from store', () => {
|
|
expect(store.getState().peers).toEqual({ [userB.userId]: peer })
|
|
peer.emit('close')
|
|
expect(store.getState().streams).toEqual({})
|
|
expect(store.getState().peers).toEqual({})
|
|
})
|
|
})
|
|
})
|
|
})
|