Fix old unit tests

This commit is contained in:
Jerko Steiner 2017-06-15 23:00:17 -04:00
parent 33b891f170
commit 46ec853280
13 changed files with 263 additions and 115 deletions

View File

@ -3,7 +3,8 @@
"extends": ["standard", "standard-react"],
"rules": {
"max-len": [2, 80, 4],
"jsx-quotes": ["error", "prefer-double"]
"jsx-quotes": ["error", "prefer-double"],
"padded-blocks": 0
},
"globals": {
"expect": true,

10
__mocks__/simple-peer.js Normal file
View File

@ -0,0 +1,10 @@
import EventEmitter from 'events'
const Peer = jest.genMockFunction().mockImplementation(() => {
let peer = new EventEmitter()
peer.destroy = jest.genMockFunction()
peer.signal = jest.genMockFunction()
Peer.instances.push(peer)
return peer
})
Peer.instances = []
export default Peer

View File

@ -0,0 +1,3 @@
import configureStore from 'redux-mock-store'
import { middlewares } from '../middlewares.js'
export default configureStore(middlewares)({})

View File

@ -12,8 +12,6 @@ import { Provider } from 'react-redux'
import { init } from '../actions/CallActions.js'
import { middlewares } from '../store.js'
// jest.useFakeTimers()
describe('App', () => {
let state
@ -25,7 +23,6 @@ describe('App', () => {
let component, node, store
function render() {
store = configureStore(middlewares)(state)
console.log(store.getState())
component = TestUtils.renderIntoDocument(
<Provider store={store}>
<App />
@ -37,7 +34,6 @@ describe('App', () => {
describe('render', () => {
it('renders without issues', () => {
render()
// jest.runAllTimers()
expect(node).toBeTruthy()
expect(init.mock.calls.length).toBe(1)
})

View File

@ -24,16 +24,16 @@ const _notify = (type, args) => dispatch => {
}, TIMEOUT)
}
export const info = () => dispatch => {
_notify('info', arguments)
export const info = function() {
return dispatch => _notify('info', arguments)(dispatch)
}
export const warn = () => dispatch => {
_notify('warning', arguments)
export const warn = function() {
return dispatch => _notify('warning', arguments)(dispatch)
}
export const error = () => dispatch => {
_notify('error', arguments)
export const error = function() {
return dispatch => _notify('error', arguments)(dispatch)
}
export function alert (message, dismissable) {

10
src/client/middlewares.js Normal file
View File

@ -0,0 +1,10 @@
import logger from 'redux-logger'
import promiseMiddleware from 'redux-promise-middleware'
import thunk from 'redux-thunk'
export const middlewares = [thunk, promiseMiddleware()]
export const create = log => {
const m = middlewares.slice()
log && m.push(logger)
return m
}

View File

@ -1,8 +0,0 @@
'use strict'
const Peer = require('simple-peer')
function init (opts) {
return Peer(opts)
}
module.exports = { init }

View File

@ -1,30 +1,23 @@
jest.unmock('../handshake.js')
jest.unmock('../peers.js')
jest.unmock('events')
jest.unmock('underscore')
jest.mock('simple-peer')
jest.mock('../../store.js')
jest.mock('../../callId.js')
jest.mock('../../iceServers.js')
const EventEmitter = require('events').EventEmitter
const Peer = require('../Peer.js')
const dispatcher = require('../../dispatcher/dispatcher.js')
const handshake = require('../handshake.js')
const peers = require('../peers.js')
import * as constants from '../../constants.js'
import * as handshake from '../handshake.js'
import Peer from 'simple-peer'
import peers from '../peers.js'
import store from '../../store.js'
import { EventEmitter } from 'events'
describe('handshake', () => {
let socket, peerInstances
let socket
beforeEach(() => {
socket = new EventEmitter()
socket.id = 'a'
peerInstances = []
Peer.init = jest.genMockFunction().mockImplementation(() => {
let peer = new EventEmitter()
peer.destroy = jest.genMockFunction()
peer.signal = jest.genMockFunction()
peerInstances.push(peer)
return peer
})
dispatcher.dispatch.mockClear()
Peer.instances = []
store.clearActions()
})
afterEach(() => peers.clear())
@ -40,7 +33,7 @@ describe('handshake', () => {
initiator: 'a'
}
socket.emit('users', payload)
expect(peerInstances.length).toBe(1)
expect(Peer.instances.length).toBe(1)
// when
payload = {
@ -50,9 +43,9 @@ describe('handshake', () => {
socket.emit('users', payload)
// then
expect(peerInstances.length).toBe(2)
expect(peerInstances[0].destroy.mock.calls.length).toBe(1)
expect(peerInstances[1].destroy.mock.calls.length).toBe(0)
expect(Peer.instances.length).toBe(2)
expect(Peer.instances[0].destroy.mock.calls.length).toBe(1)
expect(Peer.instances[1].destroy.mock.calls.length).toBe(0)
})
})
@ -73,8 +66,8 @@ describe('handshake', () => {
data
})
expect(peerInstances.length).toBe(1)
expect(peerInstances[0].signal.mock.calls.length).toBe(1)
expect(Peer.instances.length).toBe(1)
expect(Peer.instances[0].signal.mock.calls.length).toBe(1)
})
it('does nothing if no peer', () => {
@ -83,8 +76,8 @@ describe('handshake', () => {
data
})
expect(peerInstances.length).toBe(1)
expect(peerInstances[0].signal.mock.calls.length).toBe(0)
expect(Peer.instances.length).toBe(1)
expect(Peer.instances[0].signal.mock.calls.length).toBe(0)
})
})
})
@ -101,8 +94,8 @@ describe('handshake', () => {
initiator: 'a',
users: [{ id: 'a' }, { id: 'b'}]
})
expect(peerInstances.length).toBe(1)
peer = peerInstances[0]
expect(Peer.instances.length).toBe(1)
peer = Peer.instances[0]
expect(ready).toBeDefined()
})
@ -130,29 +123,37 @@ describe('handshake', () => {
describe('stream', () => {
it('adds a stream to streamStore', () => {
expect(dispatcher.dispatch.mock.calls.length).toBe(0)
store.clearActions()
let stream = {}
peer.emit('stream', stream)
expect(dispatcher.dispatch.mock.calls.length).toBe(1)
expect(dispatcher.dispatch.mock.calls).toEqual([[{
type: 'add-stream',
userId: 'b',
stream
}]])
expect(store.getActions()).toEqual([{
type: constants.STREAM_ADD,
payload: {
stream,
userId: 'b'
}
}])
})
})
describe('close', () => {
it('removes stream from streamStore', () => {
store.clearActions()
peer.emit('close')
expect(dispatcher.dispatch.mock.calls.length).toBe(1)
expect(dispatcher.dispatch.mock.calls).toEqual([[{
type: 'remove-stream',
userId: 'b'
}]])
expect(store.getActions()).toEqual([{
type: constants.NOTIFY,
payload: {
message: 'Peer connection closed',
type: 'error'
}
}, {
type: constants.STREAM_REMOVE,
payload: {
userId: 'b'
}
}])
})
})
})

View File

@ -1,68 +1,101 @@
jest.unmock('../peers.js')
jest.mock('../../window/video.js')
jest.mock('../../callId.js')
jest.mock('../../iceServers.js')
jest.mock('../../store.js')
// const configureStore = require('redux-mock-store').default
// const { middlewares } = require('../../middlewares.js')
// return configureStore(middlewares)({})
// })
jest.mock('simple-peer')
// const EventEmitter = require('events').EventEmitter
// const Peer = jest.genMockFunction().mockImplementation(() => {
// let peer = new EventEmitter()
// peer.destroy = jest.genMockFunction()
// peer.signal = jest.genMockFunction()
// Peer.instances.push(peer)
// return peer
// })
// Peer.instances = []
// return Peer
// })
const EventEmitter = require('events').EventEmitter
const Peer = require('../Peer.js')
const dispatcher = require('../../dispatcher/dispatcher.js')
const notify = require('../../action/notify.js')
const peers = require('../peers.js')
import * as constants from '../../constants.js'
import Peer from 'simple-peer'
import peers from '../peers.js'
import store from '../../store.js'
import { EventEmitter } from 'events'
import { play } from '../../window/video.js'
const { dispatch } = store
describe('peers', () => {
function createSocket () {
let socket = new EventEmitter()
const socket = new EventEmitter()
socket.id = 'user1'
return socket
}
let socket, stream, peerInstances, user
let socket, stream, user
beforeEach(() => {
dispatcher.dispatch.mockClear()
notify.warn.mockClear()
store.clearActions()
user = { id: 'user2' }
socket = createSocket()
peerInstances = []
Peer.instances = []
Peer.mockClear()
play.mockClear()
stream = { stream: true }
Peer.init = jest.genMockFunction().mockImplementation(() => {
let peer = new EventEmitter()
peer.destroy = jest.genMockFunction()
peer.signal = jest.genMockFunction()
peerInstances.push(peer)
return peer
})
})
const actions = {
connecting: {
type: constants.NOTIFY,
payload: {
message: 'Connecting to peer...',
type: 'warning'
}
},
established: {
type: constants.NOTIFY,
payload: {
message: 'Peer connection established',
type: 'warning'
}
}
}
afterEach(() => peers.clear())
describe('create', () => {
it('creates a new peer', () => {
peers.create({ socket, user, initiator: 'user2', stream })
expect(notify.warn.mock.calls).toEqual([[ 'Connecting to peer...' ]])
expect(store.getActions()).toEqual([actions.connecting])
// expect(notify.warn.mock.calls).toEqual([[ 'Connecting to peer...' ]])
expect(peerInstances.length).toBe(1)
expect(Peer.init.mock.calls.length).toBe(1)
expect(Peer.init.mock.calls[0][0].initiator).toBe(false)
expect(Peer.init.mock.calls[0][0].stream).toBe(stream)
expect(Peer.instances.length).toBe(1)
expect(Peer.mock.calls.length).toBe(1)
expect(Peer.mock.calls[0][0].initiator).toBe(false)
expect(Peer.mock.calls[0][0].stream).toBe(stream)
})
it('sets initiator correctly', () => {
peers.create({ socket, user, initiator: 'user1', stream })
expect(peerInstances.length).toBe(1)
expect(Peer.init.mock.calls.length).toBe(1)
expect(Peer.init.mock.calls[0][0].initiator).toBe(true)
expect(Peer.init.mock.calls[0][0].stream).toBe(stream)
expect(Peer.instances.length).toBe(1)
expect(Peer.mock.calls.length).toBe(1)
expect(Peer.mock.calls[0][0].initiator).toBe(true)
expect(Peer.mock.calls[0][0].stream).toBe(stream)
})
it('destroys old peer before creating new one', () => {
peers.create({ socket, user, initiator: 'user2', stream })
peers.create({ socket, user, initiator: 'user2', stream })
expect(peerInstances.length).toBe(2)
expect(Peer.init.mock.calls.length).toBe(2)
expect(peerInstances[0].destroy.mock.calls.length).toBe(1)
expect(peerInstances[1].destroy.mock.calls.length).toBe(0)
expect(Peer.instances.length).toBe(2)
expect(Peer.mock.calls.length).toBe(2)
expect(Peer.instances[0].destroy.mock.calls.length).toBe(1)
expect(Peer.instances[1].destroy.mock.calls.length).toBe(0)
})
})
@ -71,21 +104,21 @@ describe('peers', () => {
beforeEach(() => {
peers.create({ socket, user, initiator: 'user1', stream })
notify.warn.mockClear()
peer = peerInstances[0]
peer = Peer.instances[0]
})
describe('connect', () => {
beforeEach(() => peer.emit('connect'))
it('sends a notification', () => {
expect(notify.warn.mock.calls).toEqual([[
'Peer connection established'
]])
expect(store.getActions()).toEqual([
actions.connecting,
actions.established
])
})
it('dispatches "play" action', () => {
expect(dispatcher.dispatch.mock.calls).toEqual([[{ type: 'play' }]])
expect(play.mock.calls.length).toBe(1)
})
})
})
@ -98,7 +131,7 @@ describe('peers', () => {
it('returns Peer instance when found', () => {
peers.create({ socket, user, initiator: 'user2', stream })
expect(peers.get(user.id)).toBe(peerInstances[0])
expect(peers.get(user.id)).toBe(Peer.instances[0])
})
})
@ -121,7 +154,7 @@ describe('peers', () => {
peers.destroy(user.id)
expect(peerInstances[0].destroy.mock.calls.length).toEqual(1)
expect(Peer.instances[0].destroy.mock.calls.length).toEqual(1)
})
it('throws no error when peer missing', () => {
@ -140,8 +173,8 @@ describe('peers', () => {
peers.clear()
expect(peerInstances[0].destroy.mock.calls.length).toEqual(1)
expect(peerInstances[1].destroy.mock.calls.length).toEqual(1)
expect(Peer.instances[0].destroy.mock.calls.length).toEqual(1)
expect(Peer.instances[1].destroy.mock.calls.length).toEqual(1)
expect(peers.getIds()).toEqual([])
})

View File

@ -1,10 +1,11 @@
import NotifyActions from '../actions/NotifyActions.js'
import * as NotifyActions from '../actions/NotifyActions.js'
import _ from 'underscore'
import _debug from 'debug'
import peers from './peers.js'
import { dispatch } from '../store.js'
import store from '../store.js'
const debug = _debug('peercalls')
const { dispatch } = store
export function init (socket, roomName, stream) {
function createPeer (user, initiator) {

View File

@ -1,13 +1,14 @@
import CallActions from '../actions/CallActions.js'
import NotifyActions from '../actions/NotifyActions.js'
import Peer from './Peer.js'
import * as CallActions from '../actions/CallActions.js'
import * as NotifyActions from '../actions/NotifyActions.js'
import Peer from 'simple-peer'
import _ from 'underscore'
import _debug from 'debug'
import iceServers from '../iceServers.js'
import { dispatch } from '../store.js'
import store from '../store.js'
import { play } from '../window/video.js'
const debug = _debug('peercalls')
const { dispatch } = store
let peers = {}
@ -31,7 +32,7 @@ function create ({ socket, user, initiator, stream }) {
destroy(user.id)
}
const peer = peers[user.id] = Peer.init({
const peer = peers[user.id] = new Peer({
initiator: socket.id === initiator,
stream,
config: { iceServers }

View File

@ -1,10 +1,10 @@
import logger from 'redux-logger'
import promiseMiddleware from 'redux-promise-middleware'
import { create } from './middlewares.js'
import reducers from './reducers'
import thunk from 'redux-thunk'
import { applyMiddleware, createStore } from 'redux'
export const middlewares = [thunk, promiseMiddleware(), logger]
export const middlewares = create(
window.localStorage && window.localStorage.debug
)
export default createStore(
reducers,

View File

@ -0,0 +1,100 @@
import Promise from 'bluebird'
import createObjectURL from '../createObjectURL.js'
import getUserMedia from '../getUserMedia.js'
import navigator from '../navigator.js'
import { play } from '../video.js'
describe('window', () => {
describe('getUserMedia', () => {
class MediaStream {}
const stream = new MediaStream()
const constraints = { video: true }
afterEach(() => {
delete navigator.mediaDevices
delete navigator.getUserMedia
delete navigator.webkitGetUserMedia
})
it('calls navigator.mediaDevices.getUserMedia', () => {
const promise = Promise.resolve(stream)
navigator.mediaDevices = {
getUserMedia: jest.fn().mockReturnValue(promise)
}
expect(getUserMedia(constraints)).toBe(promise)
})
;['getUserMedia', 'webkitGetUserMedia'].forEach((method) => {
it(`it calls navigator.${method} as a fallback`, () => {
navigator[method] = jest.fn()
.mockImplementation(
(constraints, onSuccess, onError) => onSuccess(stream)
)
return getUserMedia(constraints)
.then(s => expect(s).toBe(stream))
})
})
it('throws error when no supported method', done => {
getUserMedia(constraints)
.asCallback(err => {
expect(err).toBeTruthy()
expect(err.message).toBe('Browser unsupported')
done()
})
})
})
describe('play', () => {
let v1, v2
beforeEach(() => {
v1 = window.document.createElement('video')
v2 = window.document.createElement('video')
window.document.body.appendChild(v1)
window.document.body.appendChild(v2)
v1.play = jest.fn()
v2.play = jest.fn()
})
afterEach(() => {
window.document.body.removeChild(v1)
window.document.body.removeChild(v2)
})
it('gets all videos and plays them', () => {
play()
expect(v1.play.mock.calls.length).toBe(1)
expect(v2.play.mock.calls.length).toBe(1)
})
it('does not fail on error', () => {
v1.play.mockImplementation(() => { throw new Error('test') })
play()
expect(v1.play.mock.calls.length).toBe(1)
expect(v2.play.mock.calls.length).toBe(1)
})
})
describe('navigator', () => {
it('exposes window.navigator', () => {
expect(navigator).toBe(window.navigator)
})
})
describe('createObjectURL', () => {
it('calls window.URL.createObjectURL', () => {
window.URL.createObjectURL = jest.fn().mockReturnValue('test')
expect(createObjectURL()).toBe('test')
})
})
})