1 | 'use strict';
|
2 |
|
3 | const {SignallingServerBootstrap} = require("../lib/SignallingServerBootstrap");
|
4 | const ClientMocks = require("./ClientMocks");
|
5 |
|
6 | describe("The signalling server bootstrap", () => {
|
7 |
|
8 | const SIGNALLING_SERVERS = [
|
9 | {
|
10 | signallingApiBase: "http://one"
|
11 | },
|
12 | {
|
13 | signallingApiBase: "http://two"
|
14 | }
|
15 | ];
|
16 |
|
17 | const NODE_ID = "NODE_ID",
|
18 | LIMIT = 50,
|
19 | ROOMS_TO_BOOTSTRAP_FROM = ['theroom', 'theotherroom'];
|
20 |
|
21 | let bootstrap,
|
22 | signallingSocket,
|
23 | httpRequestService,
|
24 | cyclonNode,
|
25 | serverOneResponse,
|
26 | serverTwoResponse;
|
27 |
|
28 | let successCallback,
|
29 | failureCallback;
|
30 |
|
31 | beforeEach(() => {
|
32 | successCallback = ClientMocks.createSuccessCallback();
|
33 | failureCallback = ClientMocks.createFailureCallback();
|
34 |
|
35 | cyclonNode = ClientMocks.mockCyclonNode();
|
36 | signallingSocket = ClientMocks.mockSignallingSocket();
|
37 | httpRequestService = ClientMocks.mockHttpRequestService();
|
38 |
|
39 |
|
40 |
|
41 |
|
42 | signallingSocket.getCurrentServerSpecs.and.returnValue(SIGNALLING_SERVERS);
|
43 | cyclonNode.getId.and.returnValue(NODE_ID);
|
44 | httpRequestService.get.and.callFake((url) => {
|
45 | if (url.indexOf("http://one/api/peers") === 0) {
|
46 | return serverOneResponse;
|
47 | } else if (url.indexOf("http://two/api/peers") === 0) {
|
48 | return serverTwoResponse;
|
49 | }
|
50 | throw new Error("Something weird happened");
|
51 | });
|
52 |
|
53 | bootstrap = new SignallingServerBootstrap(signallingSocket, httpRequestService, ROOMS_TO_BOOTSTRAP_FROM);
|
54 | });
|
55 |
|
56 | describe('constructor', () => {
|
57 |
|
58 | it('will throw an error if no rooms to bootstrap from are specified', () => {
|
59 | try {
|
60 | new SignallingServerBootstrap(signallingSocket, httpRequestService, []);
|
61 | } catch (e) {
|
62 | expect(e).toEqual(new Error('Must specify at least one room to bootstrap from'));
|
63 | }
|
64 | });
|
65 | });
|
66 |
|
67 | describe("when fetching initial peer sets", () => {
|
68 |
|
69 | it("returns combined results from all servers that respond", (done) => {
|
70 |
|
71 | serverOneResponse = Promise.resolve({
|
72 | NODE_ID: {id: NODE_ID},
|
73 | NODE_ID_ONE: {id: "NODE_ID_ONE"}
|
74 | });
|
75 | serverTwoResponse = Promise.resolve({
|
76 | NODE_ID: {id: NODE_ID},
|
77 | NODE_ID_TWO: {id: "NODE_ID_TWO"}
|
78 | });
|
79 |
|
80 | bootstrap.getInitialPeerSet(cyclonNode, LIMIT).then((result) => {
|
81 | expect(result).toEqual([
|
82 | {id: "NODE_ID_ONE"},
|
83 | {id: "NODE_ID_TWO"}
|
84 | ]);
|
85 | done();
|
86 | });
|
87 | });
|
88 |
|
89 | it("restricts the number of peers returned to that requested", (done) => {
|
90 |
|
91 | serverOneResponse = Promise.resolve({
|
92 | NODE_ID: {id: NODE_ID},
|
93 | NODE_ID_ONE: {id: "NODE_ID_ONE"}
|
94 | });
|
95 | serverTwoResponse = Promise.resolve({
|
96 | NODE_ID: {id: NODE_ID},
|
97 | NODE_ID_TWO: {id: "NODE_ID_TWO"}
|
98 | });
|
99 |
|
100 | bootstrap.getInitialPeerSet(cyclonNode, 1).then((result) => {
|
101 | expect(result.length).toBe(1);
|
102 | done();
|
103 | });
|
104 | });
|
105 |
|
106 | it("returns an empty array when no results are returned", (done) => {
|
107 |
|
108 | serverOneResponse = Promise.reject(new Error("dumb"));
|
109 | serverTwoResponse = Promise.reject(new Error("dumber"));
|
110 |
|
111 | bootstrap.getInitialPeerSet(cyclonNode, LIMIT).then((result) => {
|
112 | expect(result).toEqual([]);
|
113 | done();
|
114 | });
|
115 | });
|
116 |
|
117 | it('randomly chooses a room to sample from', async () => {
|
118 | const urls = [];
|
119 | httpRequestService.get.and.callFake((url) => {
|
120 | urls.push(url);
|
121 | });
|
122 | let randomSpy = spyOn(Math, 'random');
|
123 | randomSpy.and.returnValue(0.7);
|
124 | await bootstrap.getInitialPeerSet(cyclonNode, 1);
|
125 | expect(urls[0]).toContain(ROOMS_TO_BOOTSTRAP_FROM[1]);
|
126 | expect(urls[1]).toContain(ROOMS_TO_BOOTSTRAP_FROM[1]);
|
127 |
|
128 | randomSpy.and.returnValue(0.2);
|
129 | await bootstrap.getInitialPeerSet(cyclonNode, 1);
|
130 | expect(urls[2]).toContain(ROOMS_TO_BOOTSTRAP_FROM[0]);
|
131 | expect(urls[3]).toContain(ROOMS_TO_BOOTSTRAP_FROM[0]);
|
132 | });
|
133 | });
|
134 | });
|