Manual Reference Source Test

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()
        // })
    });
});