Fix CallActions.test.ts
This commit is contained in:
parent
7009e53037
commit
4bdd2e4cae
@ -1,26 +1,38 @@
|
||||
jest.mock('../socket')
|
||||
jest.mock('../window')
|
||||
jest.mock('../store')
|
||||
jest.mock('./SocketActions')
|
||||
|
||||
import * as CallActions from './CallActions'
|
||||
import * as SocketActions from './SocketActions'
|
||||
import * as constants from '../constants'
|
||||
import socket from '../socket'
|
||||
import storeMock from '../store'
|
||||
import { callId, getUserMedia } from '../window'
|
||||
import { MockStore } from 'redux-mock-store'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { bindActionCreators, createStore, AnyAction, combineReducers, applyMiddleware } from 'redux'
|
||||
import reducers from '../reducers'
|
||||
import { middlewares } from '../middlewares'
|
||||
|
||||
jest.useFakeTimers()
|
||||
|
||||
describe('reducers/alerts', () => {
|
||||
describe('CallActions', () => {
|
||||
|
||||
const store: MockStore = storeMock as any
|
||||
const callActions = bindActionCreators(CallActions, store.dispatch)
|
||||
let callActions: typeof CallActions
|
||||
|
||||
function allActions(state: AnyAction[] = [], action: AnyAction) {
|
||||
return [...state, action]
|
||||
}
|
||||
|
||||
const configureStore = () => createStore(
|
||||
combineReducers({...reducers, allActions }),
|
||||
applyMiddleware(...middlewares),
|
||||
)
|
||||
let store: ReturnType<typeof configureStore>
|
||||
|
||||
beforeEach(() => {
|
||||
store.clearActions();
|
||||
store = createStore(
|
||||
combineReducers({ allActions }),
|
||||
applyMiddleware(...middlewares),
|
||||
)
|
||||
callActions = bindActionCreators(CallActions, store.dispatch);
|
||||
(getUserMedia as any).fail(false);
|
||||
(SocketActions.handshake as jest.Mock).mockReturnValue(jest.fn())
|
||||
})
|
||||
@ -35,9 +47,8 @@ describe('reducers/alerts', () => {
|
||||
it('calls handshake.init when connected & got camera stream', async () => {
|
||||
const promise = callActions.init()
|
||||
socket.emit('connect')
|
||||
expect(store.getActions()).toEqual([{
|
||||
type: constants.INIT_PENDING,
|
||||
}, {
|
||||
await promise
|
||||
expect(store.getState().allActions.slice(1)).toEqual([{
|
||||
type: constants.NOTIFY,
|
||||
payload: {
|
||||
id: jasmine.any(String),
|
||||
@ -45,15 +56,14 @@ describe('reducers/alerts', () => {
|
||||
type: 'warning',
|
||||
},
|
||||
}, {
|
||||
type: constants.MESSAGE_ADD,
|
||||
type: constants.STREAM_ADD,
|
||||
payload: {
|
||||
image: null,
|
||||
message: 'Connected to server socket',
|
||||
timestamp: jasmine.any(String),
|
||||
userId: '[PeerCalls]',
|
||||
stream: jasmine.anything(),
|
||||
userId: constants.ME,
|
||||
},
|
||||
}, {
|
||||
type: constants.INIT,
|
||||
}])
|
||||
await promise
|
||||
expect((SocketActions.handshake as jest.Mock).mock.calls).toEqual([[{
|
||||
socket,
|
||||
roomName: callId,
|
||||
@ -65,23 +75,13 @@ describe('reducers/alerts', () => {
|
||||
const promise = callActions.init()
|
||||
socket.emit('connect')
|
||||
socket.emit('disconnect')
|
||||
expect(store.getActions()).toEqual([{
|
||||
type: constants.INIT_PENDING,
|
||||
}, {
|
||||
expect(store.getState().allActions.slice(1)).toEqual([{
|
||||
type: constants.NOTIFY,
|
||||
payload: {
|
||||
id: jasmine.any(String),
|
||||
message: 'Connected to server socket',
|
||||
type: 'warning',
|
||||
},
|
||||
}, {
|
||||
type: constants.MESSAGE_ADD,
|
||||
payload: {
|
||||
image: null,
|
||||
message: 'Connected to server socket',
|
||||
timestamp: jasmine.any(String),
|
||||
userId: '[PeerCalls]',
|
||||
},
|
||||
}, {
|
||||
type: constants.NOTIFY,
|
||||
payload: {
|
||||
@ -89,14 +89,6 @@ describe('reducers/alerts', () => {
|
||||
message: 'Server socket disconnected',
|
||||
type: 'error',
|
||||
},
|
||||
}, {
|
||||
type: constants.MESSAGE_ADD,
|
||||
payload: {
|
||||
image: null,
|
||||
message: 'Server socket disconnected',
|
||||
timestamp: jasmine.any(String),
|
||||
userId: '[PeerCalls]',
|
||||
},
|
||||
}])
|
||||
await promise
|
||||
})
|
||||
|
||||
@ -4,7 +4,8 @@ import * as StreamActions from './StreamActions'
|
||||
import * as constants from '../constants'
|
||||
import socket from '../socket'
|
||||
import { callId, getUserMedia } from '../window'
|
||||
import { Dispatch, GetState } from '../store'
|
||||
import { Dispatch, GetState, ThunkResult } from '../store'
|
||||
import { makeAction } from '../async'
|
||||
|
||||
export interface InitAction {
|
||||
type: 'INIT'
|
||||
@ -19,20 +20,21 @@ const initialize = (): InitializeAction => ({
|
||||
type: 'INIT',
|
||||
})
|
||||
|
||||
export const init = () => async (dispatch: Dispatch, getState: GetState) => {
|
||||
dispatch(initialize())
|
||||
export const init = (): ThunkResult<Promise<void>> =>
|
||||
async (dispatch, getState) => {
|
||||
const socket = await dispatch(connect())
|
||||
const stream = await dispatch(getCameraStream())
|
||||
|
||||
const socket = await connect(dispatch)
|
||||
const stream = await getCameraStream(dispatch)
|
||||
|
||||
SocketActions.handshake({
|
||||
dispatch(SocketActions.handshake({
|
||||
socket,
|
||||
roomName: callId,
|
||||
stream,
|
||||
})(dispatch, getState)
|
||||
}))
|
||||
|
||||
dispatch(initialize())
|
||||
}
|
||||
|
||||
export async function connect (dispatch: Dispatch) {
|
||||
export const connect = () => (dispatch: Dispatch) => {
|
||||
return new Promise<SocketIOClient.Socket>(resolve => {
|
||||
socket.once('connect', () => {
|
||||
resolve(socket)
|
||||
@ -46,7 +48,7 @@ export async function connect (dispatch: Dispatch) {
|
||||
})
|
||||
}
|
||||
|
||||
export async function getCameraStream (dispatch: Dispatch) {
|
||||
export const getCameraStream = () => async (dispatch: Dispatch) => {
|
||||
try {
|
||||
const stream = await getUserMedia({
|
||||
video: { facingMode: 'user' },
|
||||
|
||||
@ -27,15 +27,15 @@ function notify(dispatch: Dispatch, type: NotifyType, args: string[]) {
|
||||
}
|
||||
|
||||
export const info = (...args: any[]): ThunkResult<NotificationAddAction> => {
|
||||
return dispatch => notify(dispatch, 'info', args)
|
||||
return dispatch => dispatch(notify(dispatch, 'info', args))
|
||||
}
|
||||
|
||||
export const warning = (...args: any[]): ThunkResult<NotificationAddAction> => {
|
||||
return dispatch => notify(dispatch, 'warning', args)
|
||||
return dispatch => dispatch(notify(dispatch, 'warning', args))
|
||||
}
|
||||
|
||||
export const error = (...args: any[]): ThunkResult<NotificationAddAction> => {
|
||||
return dispatch => notify(dispatch, 'error', args)
|
||||
return dispatch => dispatch(notify(dispatch, 'error', args))
|
||||
}
|
||||
|
||||
function addNotification(payload: Notification): NotificationAddAction {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Action } from 'redux'
|
||||
import { Action, Dispatch } from 'redux'
|
||||
|
||||
export type PendingAction<T extends string, P> = Action<T> & Promise<P> & {
|
||||
status: 'pending'
|
||||
@ -49,9 +49,9 @@ export function isPendingAction(
|
||||
export function makeAction<A extends unknown[], T extends string, P>(
|
||||
type: T,
|
||||
impl: (...args: A) => Promise<P>,
|
||||
): (...args: A) => PendingAction<T, P>{
|
||||
): (...args: A) => PendingAction<T, P> {
|
||||
return (...args: A) => {
|
||||
const pendingAction= impl(...args) as PendingAction<T, P>
|
||||
const pendingAction = impl(...args) as PendingAction<T, P>
|
||||
pendingAction.type = type
|
||||
pendingAction.status = 'pending'
|
||||
return pendingAction
|
||||
|
||||
@ -1,13 +1,20 @@
|
||||
import { AnyAction, Middleware } from 'redux'
|
||||
import { isPendingAction, ResolvedAction, PendingAction, RejectedAction } from './action'
|
||||
import { isPendingAction, ResolvedAction, RejectedAction } from './action'
|
||||
import _debug from 'debug'
|
||||
|
||||
const debug = _debug('peercalls:async')
|
||||
|
||||
export const middleware: Middleware = store => next => (action: AnyAction) => {
|
||||
if (!isPendingAction(action)) {
|
||||
debug('NOT pending %o', action)
|
||||
return next(action)
|
||||
}
|
||||
|
||||
debug('Pending: %s %s', action.type, action.status)
|
||||
|
||||
const promise = action
|
||||
.then(payload => {
|
||||
debug('Resolved: %s resolved', action.type)
|
||||
const resolvedAction: ResolvedAction<string, unknown> = {
|
||||
payload,
|
||||
type: action.type,
|
||||
@ -17,6 +24,7 @@ export const middleware: Middleware = store => next => (action: AnyAction) => {
|
||||
})
|
||||
|
||||
// Propagate this action. Only attach listeners to the promise.
|
||||
debug('Calling next for %s %s', action.type, action.status)
|
||||
next({
|
||||
type: action.type,
|
||||
status: 'pending',
|
||||
@ -24,6 +32,7 @@ export const middleware: Middleware = store => next => (action: AnyAction) => {
|
||||
|
||||
const promise2 = promise
|
||||
.catch((err: Error) => {
|
||||
debug('Rejected: %s rejected %s', action.type, err.stack)
|
||||
const rejectedAction: RejectedAction<string> = {
|
||||
payload: err,
|
||||
type: action.type,
|
||||
@ -32,5 +41,7 @@ export const middleware: Middleware = store => next => (action: AnyAction) => {
|
||||
store.dispatch(rejectedAction)
|
||||
})
|
||||
|
||||
return promise2.then(() => action)
|
||||
return promise2.then(() => {
|
||||
return action
|
||||
})
|
||||
}
|
||||
|
||||
@ -6,9 +6,6 @@ export const ALERT_DISMISS = 'ALERT_DISMISS'
|
||||
export const ALERT_CLEAR = 'ALERT_CLEAR'
|
||||
|
||||
export const INIT = 'INIT'
|
||||
export const INIT_PENDING = `${INIT}_PENDING`
|
||||
export const INIT_FULFILLED = `${INIT}_FULFILLED`
|
||||
export const INIT_REJECTED = `${INIT}_REJECTED`
|
||||
|
||||
export const ME = '_me_'
|
||||
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { Middleware } from 'redux'
|
||||
import logger from 'redux-logger'
|
||||
import promiseMiddleware from 'redux-promise-middleware'
|
||||
import thunk from 'redux-thunk'
|
||||
import { middleware as asyncMiddleware } from './async'
|
||||
|
||||
export const middlewares = [thunk, promiseMiddleware()]
|
||||
export const middlewares: Middleware[] = [thunk, asyncMiddleware]
|
||||
export const create = (log = false) => {
|
||||
const m = middlewares.slice()
|
||||
log && m.push(logger)
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Action, applyMiddleware, createStore as _createStore, Store as ReduxStore } from 'redux'
|
||||
import { ThunkAction, ThunkDispatch } from 'redux-thunk'
|
||||
import { create } from './middlewares'
|
||||
import { middleware as asyncMiddleware }from './async'
|
||||
import reducers from './reducers'
|
||||
|
||||
export const middlewares = create(
|
||||
@ -10,7 +9,7 @@ export const middlewares = create(
|
||||
|
||||
export const createStore = () => _createStore(
|
||||
reducers,
|
||||
applyMiddleware(...middlewares, asyncMiddleware),
|
||||
applyMiddleware(...middlewares),
|
||||
)
|
||||
|
||||
export default createStore()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user