Fix broken tests
This commit is contained in:
parent
7e5c7db3f9
commit
6d3201d1fe
@ -39,6 +39,14 @@ describe('reducers/alerts', () => {
|
||||
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]'
|
||||
}
|
||||
}])
|
||||
await promise
|
||||
expect(SocketActions.handshake.mock.calls).toEqual([[{
|
||||
@ -62,6 +70,14 @@ describe('reducers/alerts', () => {
|
||||
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: {
|
||||
@ -69,6 +85,14 @@ 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
|
||||
})
|
||||
|
||||
@ -9,8 +9,3 @@ export const addMessage = ({ userId, message, timestamp, image }) => ({
|
||||
image
|
||||
}
|
||||
})
|
||||
|
||||
export const loadHistory = messages => ({
|
||||
type: constants.MESSAGES_HISTORY,
|
||||
messages
|
||||
})
|
||||
|
||||
@ -49,7 +49,7 @@ class PeerHandler {
|
||||
const { dispatch, user } = this
|
||||
const message = JSON.parse(new window.TextDecoder('utf-8').decode(object))
|
||||
debug('peer: %s, message: %o', user.id, object)
|
||||
switch (object.type) {
|
||||
switch (message.type) {
|
||||
case 'file':
|
||||
dispatch(ChatActions.addMessage({
|
||||
userId: user.id,
|
||||
@ -143,18 +143,26 @@ export const destroyPeers = () => ({
|
||||
|
||||
export const sendMessage = message => (dispatch, getState) => {
|
||||
const { peers } = getState()
|
||||
dispatch(NotifyActions.info('Sending message type: {0} to {1} peers.',
|
||||
message.type, Object.keys(peers).length))
|
||||
_.each(peers, peer => {
|
||||
debug('Sending message type: %s to %s peers.',
|
||||
message.type, Object.keys(peers).length)
|
||||
_.each(peers, (peer, userId) => {
|
||||
switch (message.type) {
|
||||
case 'file':
|
||||
dispatch(ChatActions.addMessage({
|
||||
userId: 'You',
|
||||
message: 'Send file: "' +
|
||||
message.payload.name + '" to peer: ' + peer._id,
|
||||
message.payload.name + '" to peer: ' + userId,
|
||||
timestamp: new Date().toLocaleString(),
|
||||
image: message.payload.data
|
||||
}))
|
||||
break
|
||||
default:
|
||||
dispatch(ChatActions.addMessage({
|
||||
userId: 'You',
|
||||
message: message.payload,
|
||||
timestamp: new Date().toLocaleString(),
|
||||
image: null
|
||||
}))
|
||||
}
|
||||
peer.send(JSON.stringify(message))
|
||||
})
|
||||
|
||||
@ -96,16 +96,15 @@ describe('PeerActions', () => {
|
||||
})
|
||||
|
||||
it('decodes a message', () => {
|
||||
const message = 'test'
|
||||
const object = JSON.stringify({ message })
|
||||
const payload = 'test'
|
||||
const object = JSON.stringify({ payload })
|
||||
peer.emit('data', Buffer.from(object, 'utf-8'))
|
||||
const { notifications } = store.getState()
|
||||
const keys = Object.keys(notifications)
|
||||
const n = notifications[keys[keys.length - 1]]
|
||||
expect(n).toEqual({
|
||||
id: jasmine.any(String),
|
||||
type: 'info',
|
||||
message: `${user.id}: ${message}`
|
||||
const { messages } = store.getState()
|
||||
expect(messages[messages.length - 1]).toEqual({
|
||||
userId: 'user2',
|
||||
timestamp: jasmine.any(String),
|
||||
image: null,
|
||||
message: 'test'
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -158,12 +157,12 @@ describe('PeerActions', () => {
|
||||
})
|
||||
|
||||
it('sends a message to all peers', () => {
|
||||
store.dispatch(PeerActions.sendMessage('test'))
|
||||
store.dispatch(PeerActions.sendMessage({ payload: 'test', type: 'text' }))
|
||||
const { peers } = store.getState()
|
||||
expect(peers['user2'].send.mock.calls)
|
||||
.toEqual([[ '{"message":"test"}' ]])
|
||||
.toEqual([[ '{"payload":"test","type":"text"}' ]])
|
||||
expect(peers['user3'].send.mock.calls)
|
||||
.toEqual([[ '{"message":"test"}' ]])
|
||||
.toEqual([[ '{"payload":"test","type":"text"}' ]])
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import * as ChatActions from '../actions/ChatActions.js'
|
||||
import * as NotifyActions from '../actions/NotifyActions.js'
|
||||
import * as PeerActions from '../actions/PeerActions.js'
|
||||
import * as constants from '../constants.js'
|
||||
@ -42,16 +41,6 @@ class SocketHandler {
|
||||
.filter(id => !newUsersMap[id])
|
||||
.forEach(id => peers[id].destroy())
|
||||
}
|
||||
handleMessages = (messages) => {
|
||||
const { dispatch } = this
|
||||
debug('socket messages: %o', messages)
|
||||
dispatch(ChatActions.loadHistory(messages))
|
||||
}
|
||||
handleNewMessage = (payload) => {
|
||||
const { dispatch } = this
|
||||
debug('socket message: %o', payload)
|
||||
dispatch(ChatActions.addMessage(payload))
|
||||
}
|
||||
}
|
||||
|
||||
export function handshake ({ socket, roomName, stream }) {
|
||||
@ -66,8 +55,6 @@ export function handshake ({ socket, roomName, stream }) {
|
||||
|
||||
socket.on(constants.SOCKET_EVENT_SIGNAL, handler.handleSignal)
|
||||
socket.on(constants.SOCKET_EVENT_USERS, handler.handleUsers)
|
||||
socket.on(constants.SOCKET_EVENT_MESSAGES, handler.handleMessages)
|
||||
socket.on(constants.SOCKET_EVENT_NEW_MESSAGE, handler.handleNewMessage)
|
||||
|
||||
debug('socket.id: %s', socket.id)
|
||||
debug('emit ready for room: %s', roomName)
|
||||
|
||||
@ -15,7 +15,6 @@ export default class App extends React.PureComponent {
|
||||
dismissAlert: PropTypes.func.isRequired,
|
||||
init: PropTypes.func.isRequired,
|
||||
notifications: PropTypes.objectOf(NotificationPropTypes).isRequired,
|
||||
notify: PropTypes.func.isRequired,
|
||||
messages: PropTypes.arrayOf(MessagePropTypes).isRequired,
|
||||
peers: PropTypes.object.isRequired,
|
||||
sendMessage: PropTypes.func.isRequired,
|
||||
@ -55,7 +54,6 @@ export default class App extends React.PureComponent {
|
||||
alerts,
|
||||
dismissAlert,
|
||||
notifications,
|
||||
notify,
|
||||
messages,
|
||||
onSendFile,
|
||||
peers,
|
||||
@ -79,7 +77,6 @@ export default class App extends React.PureComponent {
|
||||
<Notifications notifications={notifications} />
|
||||
<Chat
|
||||
messages={messages}
|
||||
notify={notify}
|
||||
onClose={this.handleHideChat}
|
||||
sendMessage={sendMessage}
|
||||
videos={videos}
|
||||
|
||||
@ -2,7 +2,6 @@ import Input from './Input.js'
|
||||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
import classnames from 'classnames'
|
||||
import socket from '../socket.js'
|
||||
|
||||
export const MessagePropTypes = PropTypes.shape({
|
||||
userId: PropTypes.string.isRequired,
|
||||
@ -11,11 +10,26 @@ export const MessagePropTypes = PropTypes.shape({
|
||||
image: PropTypes.string
|
||||
})
|
||||
|
||||
function Message (props) {
|
||||
const { message } = props
|
||||
return (
|
||||
<p className="message-text">
|
||||
{message.image && (
|
||||
<img src={message.image} width="100%" />
|
||||
)}
|
||||
{message.message}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
Message.propTypes = {
|
||||
message: MessagePropTypes
|
||||
}
|
||||
|
||||
export default class Chat extends React.PureComponent {
|
||||
static propTypes = {
|
||||
visible: PropTypes.bool.isRequired,
|
||||
messages: PropTypes.arrayOf(MessagePropTypes).isRequired,
|
||||
notify: PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
sendMessage: PropTypes.func.isRequired,
|
||||
videos: PropTypes.object.isRequired
|
||||
@ -35,7 +49,7 @@ export default class Chat extends React.PureComponent {
|
||||
this.scrollToBottom()
|
||||
}
|
||||
render () {
|
||||
const { messages, videos, notify, sendMessage } = this.props
|
||||
const { messages, videos, sendMessage } = this.props
|
||||
return (
|
||||
<div className={classnames('chat-container', {
|
||||
show: this.props.visible
|
||||
@ -53,7 +67,7 @@ export default class Chat extends React.PureComponent {
|
||||
{messages.length ? (
|
||||
messages.map((message, i) => (
|
||||
<div key={i}>
|
||||
{message.userId === socket.id ? (
|
||||
{message.userId === 'You' ? (
|
||||
<div className="chat-item chat-item-me">
|
||||
<div className="message">
|
||||
<span className="message-user-name">
|
||||
@ -61,7 +75,7 @@ export default class Chat extends React.PureComponent {
|
||||
</span>
|
||||
<span className="icon icon-schedule" />
|
||||
<time className="message-time">{message.timestamp}</time>
|
||||
<p className="message-text">{message.message}</p>
|
||||
<Message message={message} />
|
||||
</div>
|
||||
{message.image ? (
|
||||
<img className="chat-item-img" src={message.image} />
|
||||
@ -82,12 +96,7 @@ export default class Chat extends React.PureComponent {
|
||||
</span>
|
||||
<span className="icon icon-schedule" />
|
||||
<time className="message-time">{message.timestamp}</time>
|
||||
<p className="message-text">
|
||||
{message.image && (
|
||||
<img src={message.image} width="100%" />
|
||||
)}
|
||||
{message.message}
|
||||
</p>
|
||||
<Message message={message} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@ -104,7 +113,6 @@ export default class Chat extends React.PureComponent {
|
||||
|
||||
<Input
|
||||
videos={videos}
|
||||
notify={notify}
|
||||
sendMessage={sendMessage}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
import socket from '../socket.js'
|
||||
|
||||
export default class Input extends React.PureComponent {
|
||||
static propTypes = {
|
||||
videos: PropTypes.object.isRequired,
|
||||
notify: PropTypes.func.isRequired,
|
||||
sendMessage: PropTypes.func.isRequired
|
||||
}
|
||||
constructor () {
|
||||
@ -35,35 +32,27 @@ export default class Input extends React.PureComponent {
|
||||
})
|
||||
}
|
||||
submit = () => {
|
||||
const { videos, notify, sendMessage } = this.props
|
||||
const { sendMessage } = this.props
|
||||
const { message } = this.state
|
||||
if (message) {
|
||||
notify('You: ' + message)
|
||||
sendMessage(message)
|
||||
|
||||
const userId = socket.id
|
||||
const timestamp = new Date().toLocaleString('en-US', {
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
hour12: false
|
||||
sendMessage({
|
||||
payload: message,
|
||||
type: 'text'
|
||||
})
|
||||
let image = null
|
||||
// let image = null
|
||||
|
||||
// take snapshoot
|
||||
try {
|
||||
const video = videos[userId]
|
||||
if (video) {
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.height = video.videoHeight
|
||||
canvas.width = video.videoWidth
|
||||
const avatar = canvas.getContext('2d')
|
||||
avatar.drawImage(video, 0, 0, canvas.width, canvas.height)
|
||||
image = canvas.toDataURL()
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
const payload = { userId, message, timestamp, image }
|
||||
socket.emit('new_message', payload)
|
||||
// // take snapshoot
|
||||
// try {
|
||||
// const video = videos[userId]
|
||||
// if (video) {
|
||||
// const canvas = document.createElement('canvas')
|
||||
// canvas.height = video.videoHeight
|
||||
// canvas.width = video.videoWidth
|
||||
// const avatar = canvas.getContext('2d')
|
||||
// avatar.drawImage(video, 0, 0, canvas.width, canvas.height)
|
||||
// image = canvas.toDataURL()
|
||||
// }
|
||||
// } catch (e) {}
|
||||
}
|
||||
this.setState({ message: '' })
|
||||
}
|
||||
|
||||
@ -39,8 +39,8 @@ describe('components/Input', () => {
|
||||
it('sends a message', () => {
|
||||
TestUtils.Simulate.submit(node)
|
||||
expect(input.value).toBe('')
|
||||
expect(sendMessage.mock.calls).toEqual([[ message ]])
|
||||
expect(notify.mock.calls).toEqual([[ `You: ${message}` ]])
|
||||
expect(sendMessage.mock.calls)
|
||||
.toEqual([[ { payload: message, type: 'text' } ]])
|
||||
})
|
||||
})
|
||||
|
||||
@ -50,8 +50,8 @@ describe('components/Input', () => {
|
||||
key: 'Enter'
|
||||
})
|
||||
expect(input.value).toBe('')
|
||||
expect(sendMessage.mock.calls).toEqual([[ message ]])
|
||||
expect(notify.mock.calls).toEqual([[ `You: ${message}` ]])
|
||||
expect(sendMessage.mock.calls)
|
||||
.toEqual([[ { payload: message, type: 'text' } ]])
|
||||
})
|
||||
|
||||
it('does nothing when other key pressed', () => {
|
||||
@ -59,7 +59,6 @@ describe('components/Input', () => {
|
||||
key: 'test'
|
||||
})
|
||||
expect(sendMessage.mock.calls.length).toBe(0)
|
||||
expect(notify.mock.calls.length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -47,9 +47,9 @@ export default class Toolbar extends React.PureComponent {
|
||||
handleSendFile = () => {
|
||||
this.file.current.click()
|
||||
}
|
||||
handleSelectFiles = () => {
|
||||
handleSelectFiles = (event) => {
|
||||
Array
|
||||
.from(this.file.current.files)
|
||||
.from(event.target.files)
|
||||
.forEach(file => this.props.onSendFile(file))
|
||||
}
|
||||
render () {
|
||||
|
||||
@ -17,20 +17,23 @@ describe('components/Toolbar', () => {
|
||||
return <Toolbar
|
||||
chatVisible={this.props.chatVisible}
|
||||
onToggleChat={this.props.onToggleChat}
|
||||
onSendFile={this.props.onSendFile}
|
||||
messages={this.props.messages}
|
||||
stream={this.state.stream || this.props.stream}
|
||||
/>
|
||||
}
|
||||
}
|
||||
|
||||
let component, node, mediaStream, url, onToggleChat
|
||||
let component, node, mediaStream, url, onToggleChat, onSendFile
|
||||
function render () {
|
||||
mediaStream = new MediaStream()
|
||||
onToggleChat = jest.fn()
|
||||
onSendFile = jest.fn()
|
||||
component = TestUtils.renderIntoDocument(
|
||||
<ToolbarWrapper
|
||||
chatVisible
|
||||
onToggleChat={onToggleChat}
|
||||
onSendFile={onSendFile}
|
||||
messages={[]}
|
||||
stream={{ mediaStream, url }}
|
||||
/>
|
||||
@ -38,10 +41,8 @@ describe('components/Toolbar', () => {
|
||||
node = ReactDOM.findDOMNode(component)
|
||||
}
|
||||
|
||||
describe('render', () => {
|
||||
it('should not fail', () => {
|
||||
render()
|
||||
})
|
||||
beforeEach(() => {
|
||||
render()
|
||||
})
|
||||
|
||||
describe('handleChatClick', () => {
|
||||
@ -85,4 +86,28 @@ describe('components/Toolbar', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('handleSendFile', () => {
|
||||
it('triggers input dialog', () => {
|
||||
const sendFileButton = node.querySelector('.send-file')
|
||||
const click = jest.fn()
|
||||
const file = node.querySelector('input[type=file]')
|
||||
file.click = click
|
||||
TestUtils.Simulate.click(sendFileButton)
|
||||
expect(click.mock.calls.length).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('handleSelectFiles', () => {
|
||||
it('iterates through files and calls onSendFile for each', () => {
|
||||
const file = node.querySelector('input[type=file]')
|
||||
const files = [{ name: 'first' }]
|
||||
TestUtils.Simulate.change(file, {
|
||||
target: {
|
||||
files
|
||||
}
|
||||
})
|
||||
expect(onSendFile.mock.calls).toEqual([[ files[0] ]])
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@ -18,7 +18,6 @@ export const NOTIFY_DISMISS = 'NOTIFY_DISMISS'
|
||||
export const NOTIFY_CLEAR = 'NOTIFY_CLEAR'
|
||||
|
||||
export const MESSAGE_ADD = 'MESSAGE_ADD'
|
||||
export const MESSAGES_HISTORY = 'MESSAGES_HISTORY'
|
||||
|
||||
export const PEER_ADD = 'PEER_ADD'
|
||||
export const PEER_REMOVE = 'PEER_REMOVE'
|
||||
@ -33,8 +32,6 @@ export const PEER_EVENT_DATA = 'data'
|
||||
|
||||
export const SOCKET_EVENT_SIGNAL = 'signal'
|
||||
export const SOCKET_EVENT_USERS = 'users'
|
||||
export const SOCKET_EVENT_MESSAGES = 'messages'
|
||||
export const SOCKET_EVENT_NEW_MESSAGE = 'new_message'
|
||||
|
||||
export const STREAM_ADD = 'PEER_STREAM_ADD'
|
||||
export const STREAM_REMOVE = 'PEER_STREAM_REMOVE'
|
||||
|
||||
@ -23,7 +23,6 @@ function mapDispatchToProps (dispatch) {
|
||||
sendMessage: bindActionCreators(PeerActions.sendMessage, dispatch),
|
||||
dismissAlert: bindActionCreators(NotifyActions.dismissAlert, dispatch),
|
||||
init: bindActionCreators(CallActions.init, dispatch),
|
||||
notify: bindActionCreators(NotifyActions.info, dispatch),
|
||||
onSendFile: bindActionCreators(PeerActions.sendFile, dispatch)
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,8 +9,6 @@ export default function messages (state = defaultState, action) {
|
||||
const messages = state.asMutable()
|
||||
messages.push(action.payload)
|
||||
return Immutable(messages)
|
||||
case constants.MESSAGES_HISTORY:
|
||||
return Immutable(action.messages)
|
||||
default:
|
||||
return state
|
||||
}
|
||||
|
||||
@ -17,12 +17,4 @@ describe('reducers/messages', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('messageHistory', () => {
|
||||
it('get chat message hisotry', () => {
|
||||
let state = messages()
|
||||
state = messages(state, ChatActions.loadHistory([]))
|
||||
expect(state).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
const debug = require('debug')('peer-calls:socket')
|
||||
const _ = require('underscore')
|
||||
|
||||
const messages = {}
|
||||
|
||||
module.exports = function (socket, io) {
|
||||
socket.on('signal', payload => {
|
||||
// debug('signal: %s, payload: %o', socket.id, payload)
|
||||
@ -13,11 +11,6 @@ module.exports = function (socket, io) {
|
||||
})
|
||||
})
|
||||
|
||||
socket.on('new_message', payload => {
|
||||
addMesssage(socket.room, payload)
|
||||
io.to(socket.room).emit('new_message', payload)
|
||||
})
|
||||
|
||||
socket.on('ready', roomName => {
|
||||
debug('ready: %s, room: %s', socket.id, roomName)
|
||||
if (socket.room) socket.leave(socket.room)
|
||||
@ -26,17 +19,13 @@ module.exports = function (socket, io) {
|
||||
socket.room = roomName
|
||||
|
||||
let users = getUsers(roomName)
|
||||
let messages = getMesssages(roomName)
|
||||
|
||||
debug('ready: %s, room: %s, users: %o, messages: %o',
|
||||
socket.id, roomName, users, messages)
|
||||
debug('ready: %s, room: %s, users: %o', socket.id, roomName, users)
|
||||
|
||||
io.to(roomName).emit('users', {
|
||||
initiator: socket.id,
|
||||
users
|
||||
})
|
||||
|
||||
io.to(roomName).emit('messages', messages)
|
||||
})
|
||||
|
||||
function getUsers (roomName) {
|
||||
@ -45,14 +34,4 @@ module.exports = function (socket, io) {
|
||||
})
|
||||
}
|
||||
|
||||
function getMesssages (roomName) {
|
||||
if (_.isUndefined(messages[roomName])) {
|
||||
messages[roomName] = []
|
||||
}
|
||||
return messages[roomName]
|
||||
}
|
||||
|
||||
function addMesssage (roomName, payload) {
|
||||
getMesssages(roomName).push(payload)
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ describe('server/socket', () => {
|
||||
it('should emit users', () => {
|
||||
socket.emit('ready', 'room3')
|
||||
|
||||
expect(io.to.mock.calls).toEqual([[ 'room3' ], [ 'room3' ]])
|
||||
expect(io.to.mock.calls).toEqual([[ 'room3' ]])
|
||||
expect(io.to('room3').emit.mock.calls).toEqual([
|
||||
[
|
||||
'users', {
|
||||
@ -96,8 +96,7 @@ describe('server/socket', () => {
|
||||
id: 'socket2'
|
||||
}]
|
||||
}
|
||||
],
|
||||
['messages', []]
|
||||
]
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user