Manual Reference Source Test

test/functional/1-client.test.js

/// <reference types='jasmine' />
import { SignalingState, Topology, WebGroup, WebGroupState } from '../../src/index.browser';
import { cleanWebGroup, SIGNALING_URL, wait } from '../util/helper';
const WebGroupOptions = {
    signalingServer: SIGNALING_URL,
    autoRejoin: false,
};
/** @test {WebGroup} */
describe('🙂 - 1 client', () => {
    let wg1;
    /** @test {WebGroup#constructor} */
    it('constructor', () => {
        const wg = new WebGroup({ signalingServer: SIGNALING_URL });
        // Check members
        const id = Reflect.getOwnPropertyDescriptor(wg, 'id');
        expect(id).toBeDefined();
        expect(wg.id).toBe(0);
        expect(id.set).toBeUndefined();
        const myId = Reflect.getOwnPropertyDescriptor(wg, 'myId');
        expect(myId).toBeDefined();
        expect(wg.myId).toBe(0);
        expect(myId.set).toBeUndefined();
        const key = Reflect.getOwnPropertyDescriptor(wg, 'key');
        expect(key).toBeDefined();
        expect(wg.key).toBe('');
        expect(key.set).toBeUndefined();
        const members = Reflect.getOwnPropertyDescriptor(wg, 'members');
        expect(members).toBeDefined();
        expect(wg.members).toEqual([]);
        expect(members.set).toBeUndefined();
        const neighbors = Reflect.getOwnPropertyDescriptor(wg, 'neighbors');
        expect(neighbors).toBeDefined();
        expect(wg.neighbors).toEqual([]);
        expect(neighbors.set).toBeUndefined();
        const topology = Reflect.getOwnPropertyDescriptor(wg, 'topology');
        expect(topology).toBeDefined();
        expect(wg.topology).toBe(Topology.FULL_MESH);
        expect(topology.set).toBeUndefined();
        const state = Reflect.getOwnPropertyDescriptor(wg, 'state');
        expect(state).toBeDefined();
        expect(wg.state).toBe(WebGroupState.LEFT);
        expect(state.set).toBeUndefined();
        const signalingState = Reflect.getOwnPropertyDescriptor(wg, 'signalingState');
        expect(signalingState).toBeDefined();
        expect(wg.signalingState).toBe(SignalingState.CLOSED);
        expect(signalingState.set).toBeUndefined();
        const signalingServer = Reflect.getOwnPropertyDescriptor(wg, 'signalingServer');
        expect(signalingServer).toBeDefined();
        expect(wg.signalingServer).toBe(SIGNALING_URL);
        expect(signalingServer.set).toBeUndefined();
        expect(wg.autoRejoin).toBeTruthy();
        wg.autoRejoin = false;
        expect(wg.autoRejoin).toBeFalsy();
        // Check event handlers
        expect(wg.onMemberJoin).toBeUndefined();
        expect(wg.onMemberLeave).toBeUndefined();
        expect(wg.onMessage).toBeUndefined();
        expect(wg.onMyId).toBeUndefined();
        expect(wg.onStateChange).toBeUndefined();
        expect(wg.onSignalingStateChange).toBeUndefined();
        // Check methods
        expect(typeof wg.join).toBe('function');
        expect(typeof wg.invite).toBe('function');
        expect(typeof wg.leave).toBe('function');
        expect(typeof wg.send).toBe('function');
        expect(typeof wg.sendTo).toBe('function');
    });
    /** @test {WebGroup#join} */
    describe('join', () => {
        beforeEach(() => {
            wg1 = new WebGroup(WebGroupOptions);
        });
        afterEach(() => {
            cleanWebGroup(wg1);
            wg1.leave();
        });
        /** @test {WebGroup#onSignalingStateChange} */
        it('should change the Signaling state', (done) => {
            let called = 0;
            const states = [];
            const expected = [
                SignalingState.CONNECTING,
                SignalingState.OPEN,
                SignalingState.CHECKING,
                SignalingState.CHECKED,
                SignalingState.CHECKING,
                SignalingState.CHECKED,
            ];
            wg1.onSignalingStateChange = (state) => {
                called++;
                states.push(state);
                if (called === expected.length) {
                    wait(1000).then(() => {
                        expect(states).toEqual(expected);
                        expect(called).toEqual(expected.length);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#signalingState} */
        it('Signaling state should be CHECKED', (done) => {
            let called = 0;
            wg1.onSignalingStateChange = (state) => {
                called++;
                if (called === 6) {
                    wait(1000).then(() => {
                        expect(wg1.signalingState).toEqual(SignalingState.CHECKED);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#onStateChange} */
        it('should change the WebGroup state', (done) => {
            let called = 0;
            const states = [];
            const expected = [WebGroupState.JOINING, WebGroupState.JOINED];
            wg1.onStateChange = (state) => {
                called++;
                states.push(state);
                if (called === expected.length) {
                    wait(1000).then(() => {
                        expect(states).toEqual(expected);
                        expect(called).toEqual(expected.length);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#state} */
        it('WebGroup state should be JOINED', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    wait(1000).then(() => {
                        expect(wg1.state).toEqual(WebGroupState.JOINED);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#onMemberJoin} */
        it('should NOT be notified about new member', (done) => {
            let called1 = 0;
            wg1.onMemberJoin = () => called1++;
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    wait(1000).then(() => {
                        expect(called1).toEqual(0);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#onMemberLeave} */
        it('should NOT be notified about left member', (done) => {
            let called1 = 0;
            wg1.onMemberLeave = () => called1++;
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    wait(1000).then(() => {
                        expect(called1).toEqual(0);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#onMessage} */
        it('should NOT receive any message', (done) => {
            let called1 = 0;
            wg1.onMessage = () => called1++;
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    wait(1000).then(() => {
                        expect(called1).toEqual(0);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#onMyId} */
        it('should be called', (done) => {
            let called1 = 0;
            wg1.onMyId = (id) => {
                expect(id).toEqual(wg1.myId);
                called1++;
            };
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    wait(1000).then(() => {
                        expect(called1).toEqual(1);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#members} */
        it('should have only me as a member', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    expect(wg1.members).toEqual([wg1.myId]);
                    wait(1000).then(() => {
                        expect(wg1.members).toEqual([wg1.myId]);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#myId} */
        it('my id should not be 0', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    expect(wg1.myId).not.toEqual(0);
                    wait(1000).then(() => {
                        expect(wg1.myId).not.toEqual(0);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#id} */
        it('WebGroup id should not be 0', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    expect(wg1.id).not.toEqual(0);
                    wait(1000).then(() => {
                        expect(wg1.id).not.toEqual(0);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#key} */
        it('key should not be empty', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    expect(wg1.key).not.toEqual('');
                    wait(1000).then(() => {
                        expect(wg1.key).not.toEqual('');
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#topology} */
        it('topology should not change', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    expect(wg1.topology).toEqual(Topology.FULL_MESH);
                    wait(1000).then(() => {
                        expect(wg1.topology).toEqual(Topology.FULL_MESH);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#signalingServer} */
        it('Signaling server should not change', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    expect(wg1.signalingServer).toEqual(SIGNALING_URL);
                    wait(1000).then(() => {
                        expect(wg1.signalingServer).toEqual(SIGNALING_URL);
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#autoRejoin} */
        it('autoRejoin should be disabled', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    expect(wg1.autoRejoin).toBeFalsy();
                    wait(1000).then(() => {
                        expect(wg1.autoRejoin).toBeFalsy();
                        done();
                    });
                }
            };
            wg1.join();
        });
        /** @test {WebGroup#join} */
        it('should join with a specified key', (done) => {
            const key = 'ArtIsLongLifeIsShort';
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    expect(wg1.key).toEqual(key);
                    done();
                }
            };
            wg1.join(key);
        });
    });
    /** @test {WebGroup#leave} */
    describe('leave', () => {
        beforeEach((done) => {
            wg1 = new WebGroup(WebGroupOptions);
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.JOINED) {
                    cleanWebGroup(wg1);
                    done();
                }
            };
            wg1.join();
        });
        afterEach(() => cleanWebGroup(wg1));
        /** @test {WebGroup#onStateChange} */
        it('should change the WebGroup state', (done) => {
            let called1 = 0;
            const states = [];
            const expected = [WebGroupState.LEFT];
            wg1.onStateChange = (state) => {
                states.push(state);
                called1++;
                if (state === WebGroupState.LEFT) {
                    wait(1000).then(() => {
                        expect(called1).toEqual(expected.length);
                        expect(states).toEqual(expected);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#onSignalingStateChange} */
        it('should change the Signaling state', (done) => {
            let called1 = 0;
            const states = [];
            const expected = [SignalingState.CLOSED];
            wg1.onSignalingStateChange = (state) => {
                states.push(state);
                called1++;
                wait(1000).then(() => {
                    expect(called1).toEqual(expected.length);
                    expect(states).toEqual(expected);
                    done();
                });
            };
            wg1.leave();
        });
        /** @test {WebGroup#signalingState} */
        it('Signaling state should be CLOSED', (done) => {
            let called = 0;
            wg1.onSignalingStateChange = (state) => {
                called++;
                if (state === SignalingState.CLOSED) {
                    wait(1000).then(() => {
                        expect(called).toEqual(1);
                        expect(wg1.signalingState).toEqual(SignalingState.CLOSED);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#state} */
        it('WebGroup state should be LEFT', (done) => {
            let called = 0;
            wg1.onStateChange = (state) => {
                called++;
                if (state === WebGroupState.LEFT) {
                    wait(1000).then(() => {
                        expect(called).toEqual(1);
                        expect(wg1.state).toEqual(WebGroupState.LEFT);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#onMemberJoin} */
        it('should NOT be notified about new member', (done) => {
            let called1 = 0;
            wg1.onMemberJoin = () => called1++;
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    wait(1000).then(() => {
                        expect(called1).toEqual(0);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#onMemberLeave} */
        it('should NOT be notified about left member', (done) => {
            let called1 = 0;
            wg1.onMemberLeave = () => called1++;
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    wait(1000).then(() => {
                        expect(called1).toEqual(0);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#onMessage} */
        it('should NOT receive any message', (done) => {
            let called1 = 0;
            wg1.onMessage = () => called1++;
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    wait(1000).then(() => {
                        expect(called1).toEqual(0);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#onMyId} */
        it('should NOT be called', (done) => {
            let called1 = 0;
            wg1.onMyId = () => called1++;
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    wait(1000).then(() => {
                        expect(called1).toEqual(0);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#members} */
        it('should have no members', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    expect(wg1.members).toEqual([]);
                    wait(1000).then(() => {
                        expect(wg1.members).toEqual([]);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#myId} */
        it('my id should be 0', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    expect(wg1.myId).toEqual(0);
                    wait(1000).then(() => {
                        expect(wg1.myId).toEqual(0);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#id} */
        it('WebGroup id should be 0', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    expect(wg1.id).toEqual(0);
                    wait(1000).then(() => {
                        expect(wg1.id).toEqual(0);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#key} */
        it('key should be empty', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    expect(wg1.key).toEqual('');
                    wait(1000).then(() => {
                        expect(wg1.key).toEqual('');
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#topology} */
        it('topology should not change', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    expect(wg1.topology).toEqual(Topology.FULL_MESH);
                    wait(1000).then(() => {
                        expect(wg1.topology).toEqual(Topology.FULL_MESH);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#signalingServer} */
        it('Signaling server should not change', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    expect(wg1.signalingServer).toEqual(SIGNALING_URL);
                    wait(1000).then(() => {
                        expect(wg1.signalingServer).toEqual(SIGNALING_URL);
                        done();
                    });
                }
            };
            wg1.leave();
        });
        /** @test {WebGroup#autoRejoin} */
        it('autoRejoin should be disabled', (done) => {
            wg1.onStateChange = (state) => {
                if (state === WebGroupState.LEFT) {
                    expect(wg1.autoRejoin).toBeFalsy();
                    wait(1000).then(() => {
                        expect(wg1.autoRejoin).toBeFalsy();
                        done();
                    });
                }
            };
            wg1.leave();
        });
    });
});