Skip to content

Commit

Permalink
Fix #932 : fix start scene button in scene list, Fix #931 websocket i…
Browse files Browse the repository at this point in the history
…s not open bug (#936)

* Fix #932 : fix start scene button in scene list

* Fix #931 : WebSocket is not open bug

* Add tests on Websocket manager
  • Loading branch information
Pierre-Gilles authored Nov 9, 2020
1 parent 15c063a commit cedf198
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 22 deletions.
55 changes: 35 additions & 20 deletions front/src/routes/scene/SceneCard.jsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,49 @@
import { Text } from 'preact-i18n';
import { Component } from 'preact';
import { Link } from 'preact-router/match';
import cx from 'classnames';
import style from './style.css';

class SceneCard extends Component {
startScene = () => {
this.props.startScene(this.props.scene.selector);
startScene = async () => {
try {
await this.setState({ saving: true });
await this.props.httpClient.post(`/api/v1/scene/${this.props.scene.selector}/start`);
} catch (e) {}
// make sure the loader is displayed at least 200ms
setTimeout(() => this.setState({ saving: false }), 200);
};

render(props, {}) {
render(props, { saving }) {
return (
<div class="col-sm-6 col-lg-3">
<div class="card h-100">
<div class="card-body p-3 text-center">
<div class={style.scene_icon}>
<i class={`fe fe-${props.scene.icon}`} />
</div>
<h4>{props.scene.name}</h4>
<div class="text-muted">{props.scene.description}</div>
</div>
<div class="card-footer">
<div class="btn-list text-center">
<Link href={`${props.currentUrl}/${props.scene.selector}`} class="btn btn-outline-primary btn-sm">
<i class="fe fe-edit" />
<Text id="scene.editButton" />
</Link>
<button onClick={this.startScene} type="button" class="btn btn-outline-success btn-sm">
<i class="fe fe-play" />
<Text id="scene.startButton" />
</button>
<div
class={cx('dimmer', {
active: saving
})}
>
<div class="loader" />
<div class="dimmer-content">
<div class="card-body p-3 text-center">
<div class={style.scene_icon}>
<i class={`fe fe-${props.scene.icon}`} />
</div>
<h4>{props.scene.name}</h4>
<div class="text-muted">{props.scene.description}</div>
</div>
<div class="card-footer">
<div class="btn-list text-center">
<Link href={`${props.currentUrl}/${props.scene.selector}`} class="btn btn-outline-primary btn-sm">
<i class="fe fe-edit" />
<Text id="scene.editButton" />
</Link>
<button onClick={this.startScene} type="button" class="btn btn-outline-success btn-sm">
<i class="fe fe-play" />
<Text id="scene.startButton" />
</button>
</div>
</div>
</div>
</div>
</div>
Expand Down
9 changes: 7 additions & 2 deletions server/api/websockets/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const WebSocket = require('ws');
const { parseWebsocketMessage, formatWebsocketMessage } = require('../../utils/websocketUtils');
const { EVENTS, WEBSOCKET_MESSAGE_TYPES, ERROR_MESSAGES } = require('../../utils/constants');
const logger = require('../../utils/logger');
Expand All @@ -21,7 +22,9 @@ function sendMessageUser({ type, payload, userId }) {
return;
}
this.connections[userId].forEach((userConnection) => {
userConnection.client.send(formatWebsocketMessage(type, payload));
if (userConnection && userConnection.client && userConnection.client.readyState === WebSocket.OPEN) {
userConnection.client.send(formatWebsocketMessage(type, payload));
}
});
}

Expand All @@ -35,7 +38,9 @@ function sendMessageAllUsers({ type, payload }) {
const usersIds = Object.keys(this.connections);
usersIds.forEach((userId) => {
this.connections[userId].forEach((userConnection) => {
userConnection.client.send(formatWebsocketMessage(type, payload));
if (userConnection && userConnection.client && userConnection.client.readyState === WebSocket.OPEN) {
userConnection.client.send(formatWebsocketMessage(type, payload));
}
});
});
}
Expand Down
61 changes: 61 additions & 0 deletions server/test/websockets/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const EventEmitter = require('events');
const WebSocket = require('ws');
const { assert, fake } = require('sinon');
const WebsocketManager = require('../../api/websockets');

describe('Websockets', () => {
it('should send message to all users', () => {
const wss = new EventEmitter();
const gladys = {
event: new EventEmitter(),
};
const websocketManager = new WebsocketManager(wss, gladys);
const client = {
readyState: WebSocket.OPEN,
send: fake.returns(0),
};
const message = {
type: 'test',
payload: 'test',
};
websocketManager.userConnected({ id: 'aa0eaee9-5b90-4287-841a-0237f9d75832' }, client);
websocketManager.sendMessageAllUsers(message);
assert.calledWith(client.send, JSON.stringify(message));
});
it('should not send message to all users', () => {
const wss = new EventEmitter();
const gladys = {
event: new EventEmitter(),
};
const websocketManager = new WebsocketManager(wss, gladys);
const client = {
readyState: WebSocket.CLOSED,
send: fake.returns(0),
};
const message = {
type: 'test',
payload: 'test',
};
websocketManager.userConnected({ id: 'aa0eaee9-5b90-4287-841a-0237f9d75832' }, client);
websocketManager.sendMessageAllUsers(message);
assert.notCalled(client.send);
});
it('should send message to one users', () => {
const wss = new EventEmitter();
const gladys = {
event: new EventEmitter(),
};
const websocketManager = new WebsocketManager(wss, gladys);
const client = {
readyState: WebSocket.OPEN,
send: fake.returns(0),
};
const message = {
type: 'test',
payload: 'test',
};
websocketManager.userConnected({ id: 'aa0eaee9-5b90-4287-841a-0237f9d75832' }, client);
websocketManager.sendMessageUser({ ...message, userId: 'aa0eaee9-5b90-4287-841a-0237f9d75832' });
assert.calledWith(client.send, JSON.stringify(message));
});
});

0 comments on commit cedf198

Please sign in to comment.