jest-websocket-mock
Version:
Mock websockets and assert complex websocket interactions with Jest
55 lines (47 loc) • 1.45 kB
JavaScript
import { eventChannel, END } from "redux-saga";
import { cancel, call, delay, fork, put, take } from "redux-saga/effects";
import { actions } from "./reducer";
const RECONNECT_TIMEOUT = 6000;
function websocketInitChannel(connection) {
return eventChannel(emitter => {
const closeCallback = () => {
emitter(actions.connectionLost());
return emitter(END);
};
connection.onmessage = e => {
return emitter(actions.storeReceivedMessage(e.data));
};
connection.onclose = closeCallback;
connection.onerror = closeCallback;
return () => {
// unsubscribe function
connection.close();
};
});
}
function* sendMessage(connection) {
while (true) {
const { payload } = yield take(actions.send);
yield put(actions.storeSentMessage(payload));
yield call([connection, connection.send], payload);
}
}
export default function* saga() {
const connection = new WebSocket(`ws://${window.location.hostname}:8080`);
const channel = yield call(websocketInitChannel, connection);
yield put(actions.connectionSuccess());
const sendMessageTask = yield fork(sendMessage, connection);
try {
while (true) {
const action = yield take(channel);
yield put(action);
}
} finally {
// cancel background tasks...
channel.close();
yield cancel(sendMessageTask);
// ...and start again
yield delay(RECONNECT_TIMEOUT);
return yield call(saga);
}
}