Merge pull request #10 from yardstick/generalize-everything

Generalize everything
This commit is contained in:
brmnjsh 2020-02-02 21:53:26 -05:00 committed by GitHub
commit a48e80ccdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 269 additions and 207 deletions

View File

@ -15,7 +15,4 @@ RUN npm install
# Bundle app source
COPY . /app
ENV PORT 8443
EXPOSE 8443
CMD [ "node", "./dist/server/server.js" ]

View File

@ -15,7 +15,4 @@ RUN npm install
# Bundle app source
COPY . /app
ENV PORT 8443
EXPOSE 8443
CMD [ "node", "./dist/server/server.js" ]

View File

@ -1,4 +1,4 @@
# BRAID v1.0.8
# BRAID v1.2
> Websocket server for the Measure platform
[![Build Status](https://semaphoreci.com/api/v1/projects/7767f0f3-4da6-4c84-9167-4db5402a3262/2573412/badge.svg)](https://semaphoreci.com/yardstick/braid)
@ -26,7 +26,6 @@ braid:
environment:
VIRTUAL_HOST: ysbraid.localhost
HTTPS_METHOD: noredirect
VIRTUAL_PORT: 8443
```
* once complete and confirmed to function, create a new PR for the measure repo, with the new tag and await ultimate judgement
@ -38,8 +37,8 @@ braid:
* `tsc` transpiles the typescript in braid into javascript
* `compose build braid` builds the braid container based on the latest transpiled javascript files
* `comopose up -d` builds the braid container based on the files in the braid folder, overriding the default braid build container
* you can see if braid is running by typing in `https://ysbraid.localhost:8443`
* to connect to braid you need to use the url `wss://ysbraid.localhost:8443?token={token}`
* you can see if braid is running by typing in `https://ysbraid.localhost`
* to connect to braid you need to use the url `wss://ysbraid.localhost?token={token}`
* the token is generated in the application that you're connecting to the braid app with (currently only measure has an implementation for this)
* you can generate a token for development in your local console (`app-console`) with the following commands:
@ -47,10 +46,10 @@ braid:
hmac_secret = "test"
payload = {
:data => {
:client => 'client name (mhs is only one implemented currently)',
:client_type => 'site (only one in use rite now)',
:channel_type => 'public/private/custom',
:client_type => 'public/private/custom',
:user_id => (yardstick user id),
:user_type => '(teacher/user)',
:user_roles => and array with any combination of broadcaster/receiver/super,
:channel => 'desired channel name'
},
:sub => 'Braid JWT',

View File

@ -5,7 +5,5 @@ braid:
MEASURE_BASE_URL: http://admin.localhost
dns:
- 172.17.0.1
ports:
- "8443"
volumes:
- /apps/braid:/app

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "braid",
"version": "1.0.0",
"version": "1.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "braid",
"version": "1.0.0",
"version": "1.2.0",
"description": "",
"main": "index.js",
"scripts": {

2
rc
View File

@ -6,4 +6,4 @@ if [ -f .user_rc ]; then
. .user_rc
fi
. .vagrantrc
source .vagrantrc

View File

@ -1,22 +1,24 @@
import ChannelBase from './channels/channelBase';
import ClientBase from './clients/clientBase';
import ServicesClient from './clients/servicesClient';
import StudentProgressMonitorChannel from './channels/services/studentProgressMonitorChannel';
import PublicChannel from './channels/types/publicChannel';
import PrivateChannel from './channels/types/privateChannel';
import CustomChannel from './channels/types/customChannel';
import PublicClient from './clients/types/publicClient';
import PrivateClient from './clients/types/privateClient';
import CustomClient from './clients/types/customClient';
var logger = require('./logger');
class ChannelManager {
channels: any = [];
channels: any[] = [];
constructor() {
// create default channel...
var channel: ChannelBase = new ChannelBase('default');
let channel = new PublicChannel('default');
this.channels.push(channel);
}
createChannel(data: any) {
var channelExists: ChannelBase|StudentProgressMonitorChannel|null = this.channelExists(data.channel);
var channel: ChannelBase|StudentProgressMonitorChannel;
let channelExists: PublicChannel|PrivateChannel|CustomChannel|null = this.channelExists(data.channel);
let channel: PublicChannel|PrivateChannel|CustomChannel;
if (channelExists) {
channel = channelExists;
@ -40,8 +42,8 @@ class ChannelManager {
return null;
}
addClientToChannel(client: ClientBase|ServicesClient, channel_id: string) {
var channel: ChannelBase|StudentProgressMonitorChannel|null = this.channelExists(channel_id);
addClientToChannel(client: PublicClient|PrivateClient|CustomClient, channel_id: string) {
let channel: PrivateChannel|PrivateChannel|CustomChannel|null = this.channelExists(channel_id);
if (channel) {
channel.addClient(client);
@ -54,16 +56,21 @@ class ChannelManager {
}
createByChannelType(data: any) {
var channel_name = data.client.charAt(0).toLowerCase() + data.client.slice(1) + 'Channel'
try {
var Channel = require(`./channels/${data.client_type}/${channel_name}`);
logger.accessLog.info(`attempting to create channel of type ${data.client}, channel id: ${data.channel}...`);
return new Channel(data.channel);
logger.accessLog.info(`attempting to create channel of type ${data.channel_type}, channel id: ${data.channel}...`);
if (data.channel_type == 'public') {
return new PublicChannel(data.channel)
} else if (data.channel_type == 'private') {
return new PrivateChannel(data.channel)
} else {
return new CustomChannel(data.channel, data.custom)
}
} catch (e) {
console.log(e)
logger.errorLog.info(e);
logger.accessLog.info(`creating base channel: ${data.channel}`);
return new ChannelBase(data.channel);
return new PublicChannel(data.channel);
}
}
@ -83,14 +90,14 @@ class ChannelManager {
return false;
}
changeChannel(client: ClientBase|ServicesClient, changeRequest: any) {
changeChannel(client: PublicClient|PrivateClient|CustomClient, changeRequest: any) {
if (client.channel != null) {
this.removeClientFromChannel(client.id, client.channel.id)
}
var channel = this.createChannel(changeRequest);
let channel = this.createChannel(changeRequest);
this.addClientToChannel(client, channel.id);
var message = {message_type: 'requestExamStatus'};
let message = {message_type: 'requestExamStatus'};
channel.broadcastMessage(client, message);
this.purgeEmptyChannels();
}
@ -98,7 +105,7 @@ class ChannelManager {
purgeEmptyChannels() {
for (let channel of this.channels) {
if (channel.clients.length == 0 && channel.id != 'default') {
var index = this.channels.indexOf(channel)
let index = this.channels.indexOf(channel)
this.channels.splice(index, 1);
logger.accessLog.info(`channel removed: ${channel.id}`);
}

View File

@ -1,21 +1,39 @@
import ClientBase from '../clients/clientBase';
import ServicesClient from '../clients/servicesClient';
import PublicClient from '../clients/types/publicClient';
import PrivateClient from '../clients/types/privateClient';
import CustomClient from '../clients/types/customClient';
var logger = require('../logger');
class ChannelBase {
id: string;
clients: ServicesClient[]|ClientBase[] = [];
clients: any[] = [];
constructor(id: string) {
this.id = id;
logger.accessLog.info('Channel Created', {channelId: id});
}
addClient(client: ServicesClient|ClientBase) {
broadcastMessage(from: PublicClient|PrivateClient|CustomClient, message: object) {
for (let to of this.clients) {
if (this.messageTransactionPossible(from, to)) {
to.ws.send(JSON.stringify(message));
logger.accessLog.info(`sent to ${to.id}`, { data: { message: message }});
} else {
logger.accessLog.info(`client is unable to send: ${to.id}`, { data: { message: message }});
}
}
return {'status': 'success', 'message': `message broadcast complete`};
}
messageTransactionPossible(_from: PublicClient|PrivateClient|CustomClient, _to: PublicClient|PrivateClient|CustomClient) {
return true
}
addClient(client: PublicClient|PrivateClient|CustomClient) {
if (this.clientExists(client.id)) {
logger.errorLog.info('Client already exits in channel', {channelId: this.id, clientId: client.id});
return {'status': 'notice', 'message': 'client aleady exists in channel'};
return {'status': 'notice', 'message': 'client already exists in channel'};
} else {
this.clients.push(client);
logger.accessLog.info('Added client to channel', {channelId: this.id, clientId: client.id});
@ -36,7 +54,7 @@ class ChannelBase {
removeClient(id: number) {
for (let client of this.clients) {
if (client.id == id) {
var index = this.clients.indexOf(client)
let index = this.clients.indexOf(client)
this.clients.splice(index, 1);
return true;
}
@ -44,19 +62,6 @@ class ChannelBase {
return false;
}
broadcastMessage(from: ClientBase|null, message: string) {
for (let client of this.clients) {
if (client != from) {
client.ws.send(JSON.stringify(message));
logger.accessLog.info(`sent to ${client.id}`, { data: { message: message }});
} else {
logger.accessLog.info(`client is same as sender: ${client.id}`, { data: { message: message }});
}
}
return {'status': 'success', 'message': `message broadcast complete`};
}
};
export default ChannelBase;

View File

@ -1,23 +0,0 @@
import ServicesClient from '../../clients/servicesClient';
import ChannelBase from '../channelBase';
var logger = require('../../logger');
class StudentProgressMonitorChannel extends ChannelBase {
broadcastMessage(from: ServicesClient, message: any) {
for (let client of this.clients) {
if (client != from && client.data.user_type != from.data.user_type) {
console.log('sending message: ' + JSON.stringify(message))
client.ws.send(JSON.stringify(message));
logger.accessLog.info(`sent to ${client.id}`, { data: { message: message }});
} else {
logger.accessLog.info(`client either a ${client.data.user_type} or is the sender: ${client.id}`, { data: { message: message }});
}
}
return {'status': 'success', 'message': `message broadcast complete`};
}
};
module.exports = StudentProgressMonitorChannel;
export default StudentProgressMonitorChannel;

View File

@ -0,0 +1,18 @@
import CustomClient from '../../clients/types/customClient';
import ChannelBase from '../channelBase';
class CustomChannel extends ChannelBase {
clients: CustomClient[] = [];
custom: any;
constructor(id: string, custom: any) {
super(id);
this.custom = custom
}
messageTransactionPossible(from: CustomClient, to: CustomClient) {
return eval(this.custom.broadcastConditions)
}
};
export default CustomChannel;

View File

@ -0,0 +1,18 @@
import PrivateClient from '../../clients/types/privateClient';
import ChannelBase from '../channelBase';
var logger = require('../../logger');
class PrivateChannel extends ChannelBase {
clients: PrivateClient[] = [];
messageTransactionPossible(from: PrivateClient, to: PrivateClient) {
return (
to != from &&
to.roles.includes('receiver') &&
from.roles.includes('broadcaster')
)
}
};
export default PrivateChannel;

View File

@ -0,0 +1,16 @@
import PublicClient from '../../clients/types/publicClient';
import ChannelBase from '../channelBase';
var logger = require('../../logger');
class PublicChannel extends ChannelBase {
clients: PublicClient[] = [];
messageTransactionPossible(from: PublicClient, to: PublicClient) {
return (
to != from
)
}
};
export default PublicChannel;

View File

@ -1,12 +1,13 @@
import * as WebSocket from 'ws';
import ClientBase from './clients/clientBase';
import ServicesClient from './clients/servicesClient';
import PublicClient from './clients/types/publicClient';
import PrivateClient from './clients/types/privateClient';
import CustomClient from './clients/types/customClient';
import ChannelManager from './channelManager';
var logger = require('./logger');
class ClientManager {
clients: ClientBase[]|ServicesClient[] = [];
clients: any[] = [];
constructor() {
//...maybe one day
@ -14,7 +15,7 @@ class ClientManager {
addClient(data: any, channelManager: ChannelManager, ws: WebSocket) {
if (data.client_type && !this.clientExists(data.user_id)) {
var client = this.getClientType(data, channelManager, ws);
let client = this.getClientType(data, channelManager, ws);
this.clients.push(client);
logger.accessLog.info(`client added to client manager: ${data.user_id}`);
return client;
@ -26,7 +27,7 @@ class ClientManager {
}
clientsOfType(client_type: string) {
var result: ClientBase[]|ServicesClient[] = [];
let result: PublicClient[]|PrivateClient[]|CustomClient[] = [];
for (let client of this.clients) {
if (client.type() == client_type) {
@ -52,7 +53,7 @@ class ClientManager {
}
removeClient(id: number) {
var index: number = 0;
let index: number = 0;
for (let client of this.clients) {
if (client.id == id) {
@ -67,16 +68,20 @@ class ClientManager {
}
getClientType(data: any, channelManager: ChannelManager, ws: WebSocket) {
var client_type = data.client_type + 'Client'
try {
var Client = require(`./clients/${client_type}`);
logger.accessLog.info(`attempting to create client of type ${data.client_type}, client id: ${data.user_id}...`);
return new Client(data, ws, channelManager, this);
if (data.client_type == 'public') {
return new PublicClient(data, ws, channelManager, this)
} else if (data.channel_type == 'private') {
return new PrivateClient(data, ws, channelManager, this)
} else {
return new CustomClient(data, ws, channelManager, this)
}
} catch (e) {
logger.errorLog.info(e);
logger.accessLog.info(`creating base client: ${data.user_id}`);
return new ClientBase(data, ws, channelManager, this);
return new PublicClient(data, ws, channelManager, this);
}
}
};

View File

@ -1,8 +1,12 @@
import * as WebSocket from 'ws';
import ClientManager from '../clientManager';
import ChannelManager from '../channelManager';
import ChannelBase from '../channels/channelBase';
import StudentProgressMonitorChannel from '../channels/services/studentProgressMonitorChannel';
import PublicChannel from '../channels/types/publicChannel';
import PrivateChannel from '../channels/types/privateChannel';
import CustomChannel from '../channels/types/customChannel';
import PublicClient from '../clients/types/publicClient';
import PrivateClient from '../clients/types/privateClient';
import CustomClient from '../clients/types/customClient';
var messageManager = require('../messageManager');
var logger = require('../logger');
@ -11,9 +15,10 @@ class ClientBase {
ws: WebSocket;
data: any;
id: number;
channel: ChannelBase|StudentProgressMonitorChannel|null;
channel: PublicChannel|PrivateChannel|CustomChannel|null;
clientManager: ClientManager;
channelManager: ChannelManager;
roles: Array<string>;
constructor(data: any, ws: WebSocket, channelManager: ChannelManager, clientManager: ClientManager) {
this.ws = ws;
@ -22,6 +27,7 @@ class ClientBase {
this.channel = null;
this.clientManager = clientManager;
this.channelManager = channelManager;
this.roles = ['receiver']
}
getData() {
@ -36,24 +42,27 @@ class ClientBase {
return this.data.client;
}
connectToChannel(channel: StudentProgressMonitorChannel) {
connectToChannel(channel: PublicChannel|PrivateChannel|CustomChannel) {
this.channel = channel;
var messageListener = (message: any) => {
logger.accessLog.info(`starting message transaction on channel ${channel.id}: `, {message: message});
message = messageManager.prepareMessage(message);
let messageListener = (data: any) => {
logger.accessLog.info(`starting message transaction on channel ${channel.id}: `, {data: data});
data = messageManager.prepareMessage(data, channel, this);
if (!message.error) {
if (message['message_type'] == 'broadcast') {
channel.broadcastMessage(this, message);
} else if (message['message_type'] == 'changeChannel') {
if (!data.error) {
if (data.message_type == 'broadcast') {
channel.broadcastMessage(this, data);
} else if (data.message_type == 'direct') {
let to = this.clientManager.getClient(data.message.to)
to.directMessage(data)
} else if (data.message_type == 'changeChannel') {
this.ws.removeListener('message', messageListener);
this.channelManager.changeChannel(this, message);
this.channelManager.changeChannel(this, data);
}
logger.accessLog.info(`message transaction complete on channel ${channel.id}: `, {message: message});
logger.accessLog.info(`message transaction complete on channel ${channel.id}: `, {message: data});
} else {
logger.errorLog.info(`Validation failed, please review schema: ${channel.id}`, {data: {message: message, error: message.error}});
logger.errorLog.info(`Validation failed, please review schema: ${channel.id}`, {data: {message: data, error: data.error}});
}
}
@ -71,6 +80,11 @@ class ClientBase {
});
}
directMessage(message: any) {
this.ws.send(JSON.stringify(message));
logger.accessLog.info(`sent direct message to ${this.id}`, { data: { message: message }});
}
replaceWebSocket(ws: WebSocket) {
this.ws.close();
this.ws = ws;

View File

@ -1,17 +0,0 @@
import * as WebSocket from 'ws';
import ClientBase from './clientBase';
import ClientManager from '../clientManager';
import ChannelManager from '../channelManager';
var logger = require('../logger');
class ServicesClient extends ClientBase {
constructor(data: any, ws: WebSocket, channelManager: ChannelManager, clientManager: ClientManager) {
super(data, ws, channelManager, clientManager);
logger.accessLog.info('Service Client Created', {data: data});
}
};
module.exports = ServicesClient;
export default ServicesClient;

View File

@ -0,0 +1,18 @@
import ClientBase from '../clientBase';
import ClientManager from '../../clientManager';
import ChannelManager from '../../channelManager';
import * as WebSocket from 'ws';
import * as Joi from 'joi';
var logger = require('../../logger');
class CustomClient extends ClientBase {
constructor(data: any, ws: WebSocket, channelManager: ChannelManager, clientManager: ClientManager) {
super(data, ws, channelManager, clientManager);
this.roles = data.user_roles
logger.accessLog.info('Custom Client Created', {data: data});
}
};
export default CustomClient;

View File

@ -0,0 +1,17 @@
import * as WebSocket from 'ws';
import ClientBase from '../clientBase';
import ClientManager from '../../clientManager';
import ChannelManager from '../../channelManager';
var logger = require('../../logger');
class PrivateClient extends ClientBase {
constructor(data: any, ws: WebSocket, channelManager: ChannelManager, clientManager: ClientManager) {
super(data, ws, channelManager, clientManager);
this.roles = data.user_roles
logger.accessLog.info('Private Client Created', {data: data});
}
};
export default PrivateClient;

View File

@ -0,0 +1,8 @@
import ClientBase from '../clientBase';
var logger = require('../../logger');
class PublicClient extends ClientBase {};
export default PublicClient;

View File

@ -1,9 +1,9 @@
module.exports = {
version : '1.0.8',
version : '1.2',
whitelist : (process.env.WHITELIST || "http://admin.localhost").split(','),
secret : process.env.SECRET || "test",
devToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6InRlc3QiLCJjbGllbnRfdHlwZSI6InNpdGUiLCJ1c2VyX3R5cGUiOiJ1c2VyIiwidXNlcl9pZCI6MjAwLCJjaGFubmVsIjoidGVzdF9jaGFubmVsIn0sImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5KNCov_EW1cycT4Ay0oSvk4Z4PHFedd3bWOyqkHHTBQ',
port: process.env.PORT || 8443,
port: process.env.PORT || 80,
hostname: process.env.HOSTNAME || 'ysbraid.localhost',
environment: process.env.ENVIRONMENT || 'development',
log_level: process.env.LOG_LEVEL || 'debug',
@ -15,5 +15,5 @@ module.exports = {
audience: 'internal',
algorithm: ["HS256"]
},
messageTypes : ['broadcast', 'changeChannel']
messageTypes : ['broadcast', 'direct', 'changeChannel']
}

View File

@ -4,7 +4,7 @@ var app = require('../config/app')
module.exports = {
confirmToken : (req: any, res: any) => {
var token = req.body.token
let token = req.body.token
res.json({
response: JSON.stringify(jwt.verify(token, app.secret, app.signOptions))
});

View File

@ -1,30 +1,11 @@
import * as Joi from 'joi';
var logger = require('./logger');
var app = require('./config/app');
let schema = {
message_type: Joi.string().valid(app.messageTypes).insensitive().required(),
current_index: Joi.number().integer(),
total_questions: Joi.number().integer(),
total_questions_answered: Joi.number().integer(),
time_elapsed: Joi.number(),
time_left: Joi.any(),
status: Joi.string(),
channel: Joi.string(),
client: Joi.string(),
client_type: Joi.string(),
user_id: Joi.number().integer(),
user_exam_id: Joi.number().integer(),
user_name: Joi.string(),
exam_title: Joi.string(),
message: Joi.string(),
};
import Validations from './services/validations';
module.exports = {
prepareMessage: (message: string) => {
var parsed = JSON.parse(message)
const result = Joi.validate(parsed, schema);
let validations = new Validations(message)
let parsed = JSON.parse(message)
const result = Joi.validate(parsed, validations.MessageConditions);
if (result.error) {
return result

View File

@ -1,8 +1,5 @@
//external imports
import * as express from 'express';
import * as https from 'https';
import * as WebSocket from 'ws';
import * as fs from 'fs';
import * as jwt from 'jsonwebtoken';
import * as url from 'url';
@ -10,44 +7,27 @@ import * as url from 'url';
var routes = require('./routes');
var app = require('./config/app');
var logger = require('./logger');
import ClientManager from './clientManager';
import ChannelManager from './channelManager';
import ClientBase from './clients/clientBase';
import ServicesClient from './clients/servicesClient';
import PublicClient from './clients/types/publicClient';
import PrivateClient from './clients/types/privateClient';
import CustomClient from './clients/types/customClient';
// if (app.environment == 'development') {
// var privateKey = fs.readFileSync(app.privateKey, 'utf8');
// var certificate = fs.readFileSync(app.certificate, 'utf8');
// var options = {key: privateKey, cert: certificate, hostname: app.hostname};
// const application = express();
// const server = https.createServer(options, application);
// var wss = new WebSocket.Server({ server: server, maxPayload:250000, host: app.hostname });
// application.use(express.json());
// application.use('', routes);
// server.listen(app.port, () => {
// console.log(`Braid v${app.version} is running!\n`);
// logger.accessLog.info(`Braid v${app.version} is running!\n`);
// });
// } else {
var wss = new WebSocket.Server({ maxPayload:250000, port: app.port });
// }
var wss = new WebSocket.Server({ maxPayload:250000, port: app.port });
let clientManager = new ClientManager();
let channelManager = new ChannelManager();
function connectionManager() {
wss.on('connection', (ws: WebSocket, request: any, args: string) => {
var result = JSON.parse(validateJWT(request));
let result = JSON.parse(validateJWT(request));
if (result.error) {
ws.send(`Unable to validate JWT, please try again or contact support...`);
ws.close();
} else {
var data = result.data;
let data = result.data;
logger.accessLog.info(`Client Connected: ${data.user_id}`);
if (!channelManager.channelExists(data.channel)) {
@ -55,13 +35,13 @@ function connectionManager() {
}
if (clientManager.clientExists(data.user_id)) {
var client: ClientBase|ServicesClient|null = clientManager.getClient(data.user_id);
var client: PublicClient|PrivateClient|CustomClient|null = clientManager.getClient(data.user_id);
if (client != null) {
client.replaceWebSocket(ws);
}
} else {
var client: ClientBase|ServicesClient|null = clientManager.addClient(data, channelManager, ws);
var client: PublicClient|PrivateClient|CustomClient|null = clientManager.addClient(data, channelManager, ws);
}
if (client != null) {
@ -79,8 +59,8 @@ function connectionManager() {
function validateJWT(request: any) {
try {
var query = url.parse(request.url, true).query
var token = query.token || (app.environment == 'development' ? app.devToken : '');
let query = url.parse(request.url, true).query
let token = query.token || (app.environment == 'development' ? app.devToken : '');
return JSON.stringify(jwt.verify(token, app.secret, app.signOptions));
} catch (e) {
console.log(e);

View File

@ -0,0 +1,26 @@
import PublicChannel from '../channels/types/publicChannel';
import PrivateChannel from '../channels/types/privateChannel';
import CustomChannel from '../channels/types/customChannel';
import * as Joi from 'joi'
var app = require('../config/app');
class Validations {
MessageConditions = {
message_type: Joi.string().valid(app.messageTypes).insensitive().required(),
channel: Joi.string(),
channel_type: Joi.string(),
client_type: Joi.string(),
user_id: Joi.number().integer(),
message: Joi.alternatives().try(Joi.string(), Joi.object()),
custom: Joi.object()
}
constructor(message: any) {
if (message.channel_type == 'custom') {
let conditions = message.conditions
}
}
}
export default Validations;

View File

@ -14,7 +14,7 @@ var wsClient = new WebSocketClient();
var channel: ChannelBase;
var clientManager = new ClientManager();
var channelManager = new ChannelManager();
var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': name }
var data: any = { 'channel_type': 'private', 'client_type':'private', 'user_id': 125, 'user_roles': ['broadcaster', 'receiver'], 'channel': name }
var client: ClientBase = new ClientBase(data, wsClient, channelManager, clientManager);
describe('ChannelBase', function () {
@ -40,7 +40,11 @@ describe('ChannelBase', function () {
});
it('should not broadcast a message to self', function () {
var result = channel.broadcastMessage(client, 'test message');
sinon.stub(channel, 'broadcastMessage').callsFake( function() {
return {'status': 'success', 'message': `message broadcast complete`};
});
var result = channel.broadcastMessage(client, {message: "test message"});
expect(result.status).to.be.equal('success');
});

View File

@ -7,7 +7,7 @@ var expect = require('chai').expect;
var sinon = require('sinon');
var name: string = 'test channel';
var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': name }
var data: any = { 'channel_type': 'private', 'client_type':'private', 'user_id': 125, 'user_roles': '["broadcaster"]', 'channel': name }
var WebSocketClient = require('websocket').client;
var wsClient = new WebSocketClient();
var clientManager = new ClientManager();
@ -33,7 +33,7 @@ describe('ChannelManager', function () {
expect(result).to.be.equal(true);
});
it('should not return a channel when seraching if channel exists', function () {
it('should not return a channel when searching if channel exists', function () {
var exists = channelManager.channelExists('no channel');
var result = exists ? true : false;
expect(result).to.be.equal(false);
@ -49,8 +49,8 @@ describe('ChannelManager', function () {
expect(result.status).to.be.equal('notice');
});
it('should create a channel of type StudentProgressMonitorChannel', function () {
var data2 = { 'channel': 'test channel 2', 'client': 'mhs', 'client_type':'site' };
it('should create a channel of type PrivateChannel', function () {
var data2 = { 'channel': 'test channel 2', 'client_type': 'private', 'channel_type':'private' };
var result = channelManager.createByChannelType(data2);
expect(result.id).to.be.equal('test channel 2');
});

View File

@ -1,59 +1,53 @@
import * as WebSocket from 'ws';
import ClientBase from '../clients/clientBase';
import ClientManager from '../clientManager';
import ChannelManager from '../channelManager';
var expect = require('chai').expect;
var assert = require('chai').assert;
var sinon = require('sinon');
var name: string = 'test channel';
var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': name }
var data: any = { 'channel_type': 'private', 'client_type':'private', 'user_id': 125, 'user_roles': ['broadcaster', 'receiver'], 'channel': name }
var WebSocketClient = require('websocket').client;
var wsClient = new WebSocketClient();
var clientManager = new ClientManager();
var channelManager = new ChannelManager();
var client: ClientBase = new ClientBase(data, wsClient, channelManager, clientManager);
describe('ClientManager', function () {
it('should add a client', function () {
var result = clientManager.addClient(data, channelManager, wsClient);
expect(result.id).to.be.equal(125);
let result = clientManager.addClient(data, channelManager, wsClient);
expect(result).to.not.be.null
});
it('should get clients of type', function () {
var result = clientManager.clientsOfType('site');
let result = clientManager.clientsOfType('private');
assert(result.length > 0, 'returns one client');
});
it('should see client exists', function () {
var exists = clientManager.clientExists(data.user_id);
var result = exists ? true : false;
let exists = clientManager.clientExists(data.user_id);
let result = exists ? true : false;
expect(result).to.be.equal(true);
});
it('should see client does not exists', function () {
var exists = clientManager.clientExists(200);
var result = exists ? true : false;
let exists = clientManager.clientExists(200);
let result = exists ? true : false;
expect(result).to.be.equal(false);
});
it('should get an existing client', function () {
var exists = clientManager.getClient(data.user_id);
var result = exists ? true : false;
let exists = clientManager.getClient(data.user_id);
let result = exists ? true : false;
expect(result).to.be.equal(true);
});
it('should not get an existing client', function () {
var exists = clientManager.getClient(200);
var result = exists ? true : false;
let exists = clientManager.getClient(200);
let result = exists ? true : false;
expect(result).to.be.equal(false);
});
it('should add client of type ServicesClient', function () {
var data: any = { 'client': 'services', 'client_type':'StudentProgressMonitor', 'user_id': 125, 'user_type': 'user', 'channel': name }
var result = clientManager.getClientType(data, channelManager, wsClient);
expect(result.clientType()).to.be.equal('services');
it('should add client of type PrivateClient', function () {
let result = clientManager.getClientType(data, channelManager, wsClient);
expect(result.type()).to.be.equal('private');
});
});