test/functional/3-clients.test.js
/// <reference types='jasmine' />
/* tslint:disable:one-variable-per-declaration */
import { SignalingState, WebGroup, WebGroupState } from '../../src/index.browser';
import { areTheSame, cleanWebGroup, Queue, randomBigArrayBuffer, SIGNALING_URL, wait, } from '../util/helper';
const WebGroupOptions = {
signalingServer: SIGNALING_URL,
autoRejoin: false,
};
/** @test {WebGroup} */
describe('🙂 🙂 🙂 - 3 clients', () => {
let wg1, wg2, wg3;
let called1, called2, called3;
/** @test {WebGroup#join} */
describe('join', () => {
beforeEach((done) => {
called1 = 0;
called2 = 0;
called3 = 0;
const queue = new Queue(3, () => {
cleanWebGroup(wg1);
cleanWebGroup(wg2);
cleanWebGroup(wg3);
done();
});
wg1 = new WebGroup(WebGroupOptions);
wg2 = new WebGroup(WebGroupOptions);
wg3 = new WebGroup(WebGroupOptions);
wg1.onStateChange = (state) => {
if (state === WebGroupState.JOINED) {
wg2.join(wg1.key);
}
};
wg1.onMemberJoin = () => queue.done();
wg2.onStateChange = (state) => {
if (state === WebGroupState.JOINED) {
queue.done();
}
};
wg2.onMemberJoin = () => queue.done();
wg1.join();
});
afterEach(() => {
cleanWebGroup(wg1);
cleanWebGroup(wg2);
cleanWebGroup(wg3);
wg1.leave();
wg2.leave();
wg3.leave();
});
/** @test {WebGroup#onSignalingStateChange} */
it('should change the Signaling state', (done) => {
const states = [];
const expected = [
SignalingState.CONNECTING,
SignalingState.OPEN,
SignalingState.CHECKING,
SignalingState.CHECKED,
SignalingState.CHECKING,
SignalingState.CHECKED,
];
// Code for peer 3
wg3.onSignalingStateChange = (state) => {
states.push(state);
called3++;
if (called3 === expected.length) {
wait(1000).then(() => {
expect(called3).toEqual(6);
expect(states).toEqual(expected);
expect(wg3.signalingState).toEqual(SignalingState.CHECKED);
done();
});
}
};
wg3.join(wg1.key);
});
/** @test {WebGroup#onStateChange} */
it('should change the WebGroup state', (done) => {
const states = [];
const expected = [WebGroupState.JOINING, WebGroupState.JOINED];
// Code for peer 1
wg1.onStateChange = () => called1++;
// Code for peer 2
wg2.onStateChange = () => called2++;
// Code for peer 3
wg3.onStateChange = (state) => {
states.push(state);
called3++;
if (called3 === expected.length) {
wait(1000).then(() => {
expect(called1).toEqual(0);
expect(called2).toEqual(0);
expect(called3).toEqual(2);
expect(states).toEqual(expected);
expect(wg3.state).toEqual(WebGroupState.JOINED);
done();
});
}
};
wg3.join(wg1.key);
});
/** @test {WebGroup#onMemberJoin} */
it('should be notified about new member', (done) => {
const members3 = [];
const expectedMembers3 = [wg1.myId, wg2.myId];
const queue = new Queue(3, () => {
wait(1000).then(() => {
expect(called1).toEqual(1);
expect(called2).toEqual(1);
expect(called3).toEqual(2);
expect(areTheSame(members3, expectedMembers3)).toBeTruthy();
done();
});
});
// Code for peer 1
wg1.onMemberJoin = (id) => {
expect(id).toEqual(wg3.myId);
called1++;
queue.done();
};
// Code for peer 2
wg2.onMemberJoin = (id) => {
expect(id).toEqual(wg3.myId);
called2++;
queue.done();
};
// Code for peer 3
wg3.onMemberJoin = (id) => {
members3.push(id);
called3++;
if (called3 === 2) {
queue.done();
}
};
wg3.join(wg1.key);
});
it('should have the same members, key, WebGroup id, topology once joined', (done) => {
const queue = new Queue(3, () => {
wait(1000).then(() => {
expect(areTheSame(wg3.members, wg1.members)).toBeTruthy();
expect(areTheSame(wg3.members, wg2.members)).toBeTruthy();
expect(wg3.id).toEqual(wg1.id);
expect(wg3.key).toEqual(wg1.key);
expect(wg3.topology).toEqual(wg1.topology);
done();
});
});
// Code for peer 1
wg1.onMemberJoin = () => queue.done();
// Code for peer 2
wg2.onMemberJoin = () => queue.done();
// Code for peer 3
wg3.onStateChange = (state) => {
if (state === WebGroupState.JOINED) {
expect(wg3.members.length).toEqual(3);
expect(wg3.members.includes(wg1.myId)).toBeTruthy();
expect(wg3.members.includes(wg2.myId)).toBeTruthy();
expect(wg3.members.includes(wg3.myId)).toBeTruthy();
expect(wg3.id).toEqual(wg1.id);
expect(wg3.key).toEqual(wg1.key);
expect(wg3.topology).toEqual(wg1.topology);
queue.done();
}
};
wg3.join(wg1.key);
});
});
describe('should send/receive', () => {
beforeEach((done) => {
called1 = 0;
called2 = 0;
called3 = 0;
const queue = new Queue(9, () => {
cleanWebGroup(wg1);
cleanWebGroup(wg2);
cleanWebGroup(wg3);
done();
});
wg1 = new WebGroup(WebGroupOptions);
wg2 = new WebGroup(WebGroupOptions);
wg3 = new WebGroup(WebGroupOptions);
wg1.onMemberJoin = () => queue.done();
wg1.onStateChange = (state) => {
if (state === WebGroupState.JOINED) {
queue.done();
wg2.join(wg1.key);
}
};
wg2.onMemberJoin = () => queue.done();
wg2.onStateChange = (state) => {
if (state === WebGroupState.JOINED) {
queue.done();
wg3.join(wg1.key);
}
};
wg3.onMemberJoin = () => queue.done();
wg3.onStateChange = (state) => {
if (state === WebGroupState.JOINED) {
queue.done();
}
};
wg1.join();
});
afterEach(() => {
cleanWebGroup(wg1);
cleanWebGroup(wg2);
cleanWebGroup(wg3);
wg1.leave();
wg2.leave();
wg3.leave();
});
/** @test {WebGroup#send} */
it('broadcast String', (done) => {
const queue = new Queue(6, () => {
wait(1000).then(() => {
expect(called1).toEqual(2);
expect(called2).toEqual(2);
expect(called3).toEqual(2);
expect(areTheSame(messages1.ids, [wg2.myId, wg3.myId])).toBeTruthy();
expect(areTheSame(messages1.msgs, [msg2, msg3])).toBeTruthy();
expect(areTheSame(messages2.ids, [wg1.myId, wg3.myId])).toBeTruthy();
expect(areTheSame(messages2.msgs, [msg1, msg3])).toBeTruthy();
expect(areTheSame(messages3.ids, [wg2.myId, wg1.myId])).toBeTruthy();
expect(areTheSame(messages3.msgs, [msg2, msg1])).toBeTruthy();
done();
});
});
const msg1 = 'Art is long, life is short';
const msg2 = 'Do or do not, there is no try';
const msg3 = 'Never say never';
const messages1 = { ids: [], msgs: [] };
const messages2 = { ids: [], msgs: [] };
const messages3 = { ids: [], msgs: [] };
// Code for peer 1
wg1.onMessage = (id, msg) => {
messages1.ids.push(id);
messages1.msgs.push(msg);
called1++;
queue.done();
};
// Code for peer 2
wg2.onMessage = (id, msg) => {
messages2.ids.push(id);
messages2.msgs.push(msg);
called2++;
queue.done();
};
// Code for peer 3
wg3.onMessage = (id, msg) => {
messages3.ids.push(id);
messages3.msgs.push(msg);
called3++;
queue.done();
};
// Start sending message
wg1.send(msg1);
wg2.send(msg2);
wg3.send(msg3);
});
/** @test {WebGroup#send} */
it('broadcast ArrayBuffer', (done) => {
const queue = new Queue(6, () => {
wait(1000).then(() => {
expect(called1).toEqual(2);
expect(called2).toEqual(2);
expect(called3).toEqual(2);
expect(areTheSame(messages1.ids, [wg2.myId, wg3.myId])).toBeTruthy();
expect(areTheSame(messages1.msgs, [msg2, msg3])).toBeTruthy();
expect(areTheSame(messages2.ids, [wg1.myId, wg3.myId])).toBeTruthy();
expect(areTheSame(messages2.msgs, [msg1, msg3])).toBeTruthy();
expect(areTheSame(messages3.ids, [wg2.myId, wg1.myId])).toBeTruthy();
expect(areTheSame(messages3.msgs, [msg2, msg1])).toBeTruthy();
done();
});
});
const msg1 = new Uint8Array([42, 347, 248247, 583, 10, 8, 9623]);
const msg2 = new Uint8Array([845, 4, 798240, 3290, 553, 1, 398539857, 84]);
const msg3 = new Uint8Array([84, 79, 240, 30, 53, 3, 339857, 44]);
const messages1 = { ids: [], msgs: [] };
const messages2 = { ids: [], msgs: [] };
const messages3 = { ids: [], msgs: [] };
// Code for peer 1
wg1.onMessage = (id, msg) => {
expect(msg instanceof Uint8Array).toBeTruthy();
messages1.ids.push(id);
messages1.msgs.push(msg);
called1++;
queue.done();
};
// Code for peer 2
wg2.onMessage = (id, msg) => {
expect(msg instanceof Uint8Array).toBeTruthy();
messages2.ids.push(id);
messages2.msgs.push(msg);
called2++;
queue.done();
};
// Code for peer 3
wg3.onMessage = (id, msg) => {
expect(msg instanceof Uint8Array).toBeTruthy();
messages3.ids.push(id);
messages3.msgs.push(msg);
called3++;
queue.done();
};
// Start sending message
wg1.send(msg1);
wg2.send(msg2);
wg3.send(msg3);
});
/** @test {WebGroup#sendTo} */
it('broadcast message cutted in chunks (> 15kb)', (done) => {
const bytes = randomBigArrayBuffer();
const queue = new Queue(2, () => {
wait(1000).then(() => {
expect(called2).toEqual(1);
expect(called3).toEqual(1);
done();
});
});
// Code for peer 2
wg2.onMessage = (id, msg) => {
expect(msg instanceof Uint8Array).toBeTruthy();
expect(msg).toEqual(bytes);
called2++;
queue.done();
};
// Code for peer 3
wg3.onMessage = (id, msg) => {
expect(msg instanceof Uint8Array).toBeTruthy();
expect(msg).toEqual(bytes);
called3++;
queue.done();
};
// Start sending message
wg1.send(bytes);
});
/** @test {WebGroup#sendTo} */
it('private String', (done) => {
const queue = new Queue(6, () => {
wait(1000).then(() => {
expect(called1).toEqual(2);
expect(called2).toEqual(2);
expect(called3).toEqual(2);
expect(areTheSame(messages1.ids, [wg2.myId, wg3.myId])).toBeTruthy();
expect(areTheSame(messages1.msgs, [msg2For1, msg3For1])).toBeTruthy();
expect(areTheSame(messages2.ids, [wg1.myId, wg3.myId])).toBeTruthy();
expect(areTheSame(messages2.msgs, [msg1For2, msg3For2])).toBeTruthy();
expect(areTheSame(messages3.ids, [wg2.myId, wg1.myId])).toBeTruthy();
expect(areTheSame(messages3.msgs, [msg2For3, msg1For3])).toBeTruthy();
done();
});
});
const msg1For2 = 'Art is long, life is short2';
const msg1For3 = 'Art is long, life is short3';
const msg2For1 = 'Do or do not, there is no try1';
const msg2For3 = 'Do or do not, there is no try3';
const msg3For1 = 'Never say never1';
const msg3For2 = 'Never say never2';
const messages1 = { ids: [], msgs: [] };
const messages2 = { ids: [], msgs: [] };
const messages3 = { ids: [], msgs: [] };
// Code for peer 1
wg1.onMessage = (id, msg) => {
messages1.ids.push(id);
messages1.msgs.push(msg);
called1++;
queue.done();
};
// Code for peer 2
wg2.onMessage = (id, msg) => {
messages2.ids.push(id);
messages2.msgs.push(msg);
called2++;
queue.done();
};
// Code for peer 3
wg3.onMessage = (id, msg) => {
messages3.ids.push(id);
messages3.msgs.push(msg);
called3++;
queue.done();
};
// Start sending message
wg1.sendTo(wg2.myId, msg1For2);
wg1.sendTo(wg3.myId, msg1For3);
wg2.sendTo(wg1.myId, msg2For1);
wg2.sendTo(wg3.myId, msg2For3);
wg3.sendTo(wg1.myId, msg3For1);
wg3.sendTo(wg2.myId, msg3For2);
});
/** @test {WebGroup#sendTo} */
it('private ArrayBuffer', (done) => {
const queue = new Queue(6, () => {
wait(1000).then(() => {
expect(called1).toEqual(2);
expect(called2).toEqual(2);
expect(called3).toEqual(2);
expect(areTheSame(messages1.ids, [wg2.myId, wg3.myId])).toBeTruthy();
expect(areTheSame(messages1.msgs, [msg2For1, msg3For1])).toBeTruthy();
expect(areTheSame(messages2.ids, [wg1.myId, wg3.myId])).toBeTruthy();
expect(areTheSame(messages2.msgs, [msg1For2, msg3For2])).toBeTruthy();
expect(areTheSame(messages3.ids, [wg2.myId, wg1.myId])).toBeTruthy();
expect(areTheSame(messages3.msgs, [msg2For3, msg1For3])).toBeTruthy();
done();
});
});
const msg1For2 = new Uint8Array([42, 347, 248247, 583, 10, 8, 2]);
const msg1For3 = new Uint8Array([42, 347, 248247, 583, 10, 8, 3]);
const msg2For1 = new Uint8Array([845, 4, 798240, 3290, 553, 1, 398539857, 1]);
const msg2For3 = new Uint8Array([845, 4, 798240, 3290, 553, 1, 398539857, 3]);
const msg3For1 = new Uint8Array([84, 79, 240, 30, 53, 3, 339857, 1]);
const msg3For2 = new Uint8Array([84, 79, 240, 30, 53, 3, 339857, 2]);
const messages1 = { ids: [], msgs: [] };
const messages2 = { ids: [], msgs: [] };
const messages3 = { ids: [], msgs: [] };
// Code for peer 1
wg1.onMessage = (id, msg) => {
expect(msg instanceof Uint8Array).toBeTruthy();
messages1.ids.push(id);
messages1.msgs.push(msg);
called1++;
queue.done();
};
// Code for peer 2
wg2.onMessage = (id, msg) => {
expect(msg instanceof Uint8Array).toBeTruthy();
messages2.ids.push(id);
messages2.msgs.push(msg);
called2++;
queue.done();
};
// Code for peer 3
wg3.onMessage = (id, msg) => {
expect(msg instanceof Uint8Array).toBeTruthy();
messages3.ids.push(id);
messages3.msgs.push(msg);
called3++;
queue.done();
};
// Start sending message
wg1.sendTo(wg2.myId, msg1For2);
wg1.sendTo(wg3.myId, msg1For3);
wg2.sendTo(wg1.myId, msg2For1);
wg2.sendTo(wg3.myId, msg2For3);
wg3.sendTo(wg1.myId, msg3For1);
wg3.sendTo(wg2.myId, msg3For2);
});
});
// TODO: finish test
xdescribe('leave', () => {
// beforeEach((done) => {
// called1 = 0
// called2 = 0
// called3 = 0
// const queue = new Queue(4)
// queue.wait().then(() => {
// cleanWebGroup(wg1)
// cleanWebGroup(wg2)
// cleanWebGroup(wg3)
// done()
// })
// wg1 = new WebGroup(WebGroupOptions)
// wg2 = new WebGroup(WebGroupOptions)
// wg3 = new WebGroup(WebGroupOptions)
// wg1.onSignalingStateChange = (state: SignalingState) => {
// if (state === SignalingState.STABLE) {
// wg2.join(wg1.key)
// }
// }
// wg1.onMemberJoin = () => queue.done()
// wg2.onStateChange = (state: WebGroupState) => {
// if (state === WebGroupState.JOINED) {
// queue.done()
// }
// }
// wg2.onSignalingStateChange = (state: SignalingState) => {
// if (state === SignalingState.STABLE) {
// queue.done()
// }
// }
// wg2.onMemberJoin = () => queue.done()
// wg1.join()
// })
// afterEach((done) => {
// cleanWebGroup(wg1)
// cleanWebGroup(wg2)
// cleanWebGroup(wg3)
// const queue = new Queue(3)
// if (wg1.state !== WebGroup.LEFT) {
// wg1.onStateChange = (state: WebGroupState) => {
// if (state === WebGroup.LEFT) {
// queue.done()
// }
// }
// wg1.leave()
// } else {
// queue.done()
// }
// if (wg2.state !== WebGroup.LEFT) {
// wg2.onStateChange = (state: WebGroupState) => {
// if (state === WebGroup.LEFT) {
// queue.done()
// }
// }
// wg2.leave()
// } else {
// queue.done()
// }
// if (wg3.state !== WebGroup.LEFT) {
// wg3.onStateChange = (state: WebGroupState) => {
// if (state === WebGroup.LEFT) {
// queue.done()
// }
// }
// wg3.leave()
// } else {
// queue.done()
// }
// queue.wait().then(() => {
// cleanWebGroup(wg1)
// cleanWebGroup(wg2)
// cleanWebGroup(wg3)
// done()
// })
// })
// /** @test {WebGroup#leave} */
// it('should have no members & an empty key', (done) => {
// const queue = new Queue(1)
// // Code for peer 1
// wg1.onMemberLeave = () => {
// expect(wg1.members.length).toEqual(1)
// expect(wg1.members.includes(wg1.myId)).toBeTruthy()
// queue.done()
// }
// // Code for peer 2
// wg2.onStateChange = (state: WebGroupState) => {
// if (state === WebGroup.LEFT) {
// called2++
// expect(wg2.members.length).toEqual(1)
// expect(wg2.members.includes(wg2.myId)).toBeTruthy()
// expect(wg2.key).toEqual('')
// queue
// .wait()
// .then(() => wait(1000))
// .then(() => {
// expect(wg1.members.length).toEqual(1)
// expect(wg1.members.includes(wg1.myId)).toBeTruthy()
// expect(wg2.members.length).toEqual(1)
// expect(wg2.members.includes(wg2.myId)).toBeTruthy()
// expect(wg2.key).toEqual('')
// expect(called2).toEqual(1)
// expect(wg2.key).toEqual('')
// done()
// })
// }
// }
// wg2.leave()
// })
// /** @test {WebGroup#onMemberLeave} */
// it('should be notified about left member', (done) => {
// const queue = new Queue(2)
// // Code for peer 1
// wg1.onMemberLeave = (id) => {
// expect(id).toEqual(wg2.myId)
// called1++
// queue.done()
// }
// // Code for peer 2
// wg2.onMemberLeave = (id) => {
// expect(id).toEqual(wg1.myId)
// called2++
// queue.done()
// }
// wg2.leave()
// // When finish test
// queue.wait().then(() => {
// wait(1000).then(() => {
// expect(called1).toEqual(1)
// expect(called2).toEqual(1)
// done()
// })
// })
// })
// /** @test {WebGroup#onStateChange} */
// it('should change the WebGroup state', (done) => {
// // Code for peer 2
// wg2.onStateChange = (state: WebGroupState) => {
// if (state === WebGroup.LEFT) {
// called2++
// }
// wait(1000).then(() => {
// expect(called2).toEqual(1)
// expect(wg2.state).toEqual(WebGroup.LEFT)
// done()
// })
// }
// wg2.leave()
// })
// /** @test {WebGroup#onSignalingStateChange} */
// it('should change the Signaling state', (done) => {
// // Code for peer 2
// wg2.onSignalingStateChange = (state: SignalingState) => {
// if (state === SignalingState.CLOSED) {
// called2++
// }
// wait(1000).then(() => {
// expect(called2).toEqual(1)
// expect(wg2.signalingState).toEqual(SignalingState.CLOSED)
// done()
// })
// }
// wg2.leave()
// })
});
});