@webex/plugin-meetings 3.0.0-beta.185 → 3.0.0-beta.187
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/common/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.js +50 -16
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/parser.js +174 -59
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/meeting/muteState.js +1 -1
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +7 -44
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +1 -1
- package/dist/meeting/util.js.map +1 -1
- package/dist/types/common/queue.d.ts +9 -7
- package/dist/types/locus-info/index.d.ts +7 -0
- package/dist/types/locus-info/parser.d.ts +50 -6
- package/dist/types/meeting/request.d.ts +3 -16
- package/package.json +19 -19
- package/src/common/queue.ts +22 -8
- package/src/locus-info/index.ts +53 -15
- package/src/locus-info/parser.ts +180 -38
- package/src/meeting/muteState.ts +1 -1
- package/src/meeting/request.ts +6 -47
- package/src/meeting/util.ts +1 -1
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/locus-info/index.js +352 -15
- package/test/unit/spec/locus-info/parser.js +0 -22
- package/test/unit/spec/meeting/muteState.js +1 -1
- package/test/unit/spec/meeting/utils.js +5 -5
|
@@ -3,6 +3,7 @@ import sinon from 'sinon';
|
|
|
3
3
|
import {cloneDeep} from 'lodash';
|
|
4
4
|
import {assert} from '@webex/test-helper-chai';
|
|
5
5
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
6
|
+
import testUtils from '../../../utils/testUtils';
|
|
6
7
|
import Meetings from '@webex/plugin-meetings';
|
|
7
8
|
import LocusInfo from '@webex/plugin-meetings/src/locus-info';
|
|
8
9
|
import SelfUtils from '@webex/plugin-meetings/src/locus-info/selfUtils';
|
|
@@ -1547,6 +1548,7 @@ describe('plugin-meetings', () => {
|
|
|
1547
1548
|
meeting: true,
|
|
1548
1549
|
participants: true,
|
|
1549
1550
|
url: 'newLocusUrl',
|
|
1551
|
+
syncUrl: 'newSyncUrl',
|
|
1550
1552
|
};
|
|
1551
1553
|
});
|
|
1552
1554
|
|
|
@@ -1707,39 +1709,82 @@ describe('plugin-meetings', () => {
|
|
|
1707
1709
|
assert.calledWith(meeting.locusInfo.onDeltaLocus, fakeLocus);
|
|
1708
1710
|
});
|
|
1709
1711
|
|
|
1710
|
-
it('applyLocusDeltaData gets
|
|
1712
|
+
it('applyLocusDeltaData gets delta locus on DESYNC action if we have a syncUrl', () => {
|
|
1711
1713
|
const {DESYNC} = LocusDeltaParser.loci;
|
|
1714
|
+
const fakeDeltaLocus = {id: 'fake delta locus'};
|
|
1712
1715
|
const meeting = {
|
|
1713
1716
|
meetingRequest: {
|
|
1714
|
-
|
|
1717
|
+
getLocusDTO: sandbox.stub().resolves({body: fakeDeltaLocus}),
|
|
1715
1718
|
},
|
|
1716
1719
|
locusInfo: {
|
|
1720
|
+
handleLocusDelta: sandbox.stub(),
|
|
1721
|
+
},
|
|
1722
|
+
locusUrl: 'oldLocusUrl',
|
|
1723
|
+
};
|
|
1724
|
+
|
|
1725
|
+
locusInfo.locusParser.workingCopy = {
|
|
1726
|
+
syncUrl: 'oldSyncUrl',
|
|
1727
|
+
};
|
|
1728
|
+
|
|
1729
|
+
// Since we have a promise inside a function we want to test that's not returned,
|
|
1730
|
+
// we will wait and stub it's last function to resolve this waiting promise.
|
|
1731
|
+
// Also ensures .handleLocusDelta() is called before .resume()
|
|
1732
|
+
return new Promise((resolve) => {
|
|
1733
|
+
locusInfo.locusParser.resume = sandbox.stub().callsFake(() => resolve());
|
|
1734
|
+
locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
|
|
1735
|
+
}).then(() => {
|
|
1736
|
+
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, { url: 'oldSyncUrl' });
|
|
1737
|
+
|
|
1738
|
+
assert.calledOnceWithExactly(meeting.locusInfo.handleLocusDelta, fakeDeltaLocus, meeting);
|
|
1739
|
+
assert.calledOnce(locusInfo.locusParser.resume);
|
|
1740
|
+
});
|
|
1741
|
+
});
|
|
1742
|
+
|
|
1743
|
+
it('applyLocusDeltaData gets delta locus on DESYNC action if we have a syncUrl (empty response body)', () => {
|
|
1744
|
+
const {DESYNC} = LocusDeltaParser.loci;
|
|
1745
|
+
const meeting = {
|
|
1746
|
+
meetingRequest: {
|
|
1747
|
+
getLocusDTO: sandbox.stub().resolves({body: {}}),
|
|
1748
|
+
},
|
|
1749
|
+
locusInfo: {
|
|
1750
|
+
handleLocusDelta: sandbox.stub(),
|
|
1717
1751
|
onFullLocus: sandbox.stub(),
|
|
1718
1752
|
},
|
|
1719
1753
|
locusUrl: 'oldLocusUrl',
|
|
1720
1754
|
};
|
|
1721
1755
|
|
|
1722
|
-
locusInfo.locusParser.
|
|
1723
|
-
|
|
1756
|
+
locusInfo.locusParser.workingCopy = {
|
|
1757
|
+
syncUrl: 'oldSyncUrl',
|
|
1758
|
+
};
|
|
1724
1759
|
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1760
|
+
// Since we have a promise inside a function we want to test that's not returned,
|
|
1761
|
+
// we will wait and stub it's last function to resolve this waiting promise.
|
|
1762
|
+
return new Promise((resolve) => {
|
|
1763
|
+
locusInfo.locusParser.resume = sandbox.stub().callsFake(() => resolve());
|
|
1764
|
+
locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
|
|
1765
|
+
}).then(() => {
|
|
1766
|
+
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, { url: 'oldSyncUrl' });
|
|
1767
|
+
|
|
1768
|
+
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
|
1769
|
+
assert.notCalled(meeting.locusInfo.onFullLocus);
|
|
1770
|
+
assert.calledOnce(locusInfo.locusParser.resume);
|
|
1771
|
+
});
|
|
1731
1772
|
});
|
|
1732
1773
|
|
|
1733
|
-
it('
|
|
1774
|
+
it('applyLocusDeltaData gets full locus on DESYNC action if we do not have a syncUrl', () => {
|
|
1734
1775
|
const {DESYNC} = LocusDeltaParser.loci;
|
|
1776
|
+
const fakeFullLocusDto = {id: 'fake full locus dto'};
|
|
1735
1777
|
const meeting = {
|
|
1736
1778
|
meetingRequest: {
|
|
1737
|
-
|
|
1779
|
+
getLocusDTO: sandbox.stub().resolves({body: fakeFullLocusDto}),
|
|
1780
|
+
},
|
|
1781
|
+
locusInfo: {
|
|
1782
|
+
onFullLocus: sandbox.stub(),
|
|
1738
1783
|
},
|
|
1739
|
-
|
|
1784
|
+
locusUrl: 'oldLocusUrl',
|
|
1740
1785
|
};
|
|
1741
1786
|
|
|
1742
|
-
locusInfo.
|
|
1787
|
+
locusInfo.locusParser.workingCopy = {}; // no syncUrl
|
|
1743
1788
|
|
|
1744
1789
|
// Since we have a promise inside a function we want to test that's not returned,
|
|
1745
1790
|
// we will wait and stub it's last function to resolve this waiting promise.
|
|
@@ -1748,7 +1793,9 @@ describe('plugin-meetings', () => {
|
|
|
1748
1793
|
locusInfo.locusParser.resume = sandbox.stub().callsFake(() => resolve());
|
|
1749
1794
|
locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
|
|
1750
1795
|
}).then(() => {
|
|
1751
|
-
assert.
|
|
1796
|
+
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, { url: 'oldLocusUrl' });
|
|
1797
|
+
|
|
1798
|
+
assert.calledOnceWithExactly(meeting.locusInfo.onFullLocus, fakeFullLocusDto);
|
|
1752
1799
|
assert.calledOnce(locusInfo.locusParser.resume);
|
|
1753
1800
|
});
|
|
1754
1801
|
});
|
|
@@ -2083,5 +2130,295 @@ describe('plugin-meetings', () => {
|
|
|
2083
2130
|
});
|
|
2084
2131
|
});
|
|
2085
2132
|
});
|
|
2133
|
+
|
|
2134
|
+
// semi-integration tests that use real LocusInfo with real Parser
|
|
2135
|
+
// and test various scenarios related to handling out-of-order Locus delta events
|
|
2136
|
+
describe('handling of out-of-order Locus delta events', () => {
|
|
2137
|
+
let clock;
|
|
2138
|
+
|
|
2139
|
+
const generateDeltaEvent = (base, sequence) => {
|
|
2140
|
+
return {
|
|
2141
|
+
baseSequence: {
|
|
2142
|
+
rangeStart: 0,
|
|
2143
|
+
rangeEnd: 0,
|
|
2144
|
+
entries: [base]
|
|
2145
|
+
},
|
|
2146
|
+
sequence: {
|
|
2147
|
+
rangeStart: 0,
|
|
2148
|
+
rangeEnd: 0,
|
|
2149
|
+
entries: [sequence]
|
|
2150
|
+
},
|
|
2151
|
+
syncUrl: `fake sync url for sequence ${sequence}`,
|
|
2152
|
+
self: {
|
|
2153
|
+
person: {
|
|
2154
|
+
id: 'test person id'
|
|
2155
|
+
}
|
|
2156
|
+
},
|
|
2157
|
+
}
|
|
2158
|
+
};
|
|
2159
|
+
|
|
2160
|
+
// a list of example delta events, sorted by time and each event is based on the previous one
|
|
2161
|
+
const deltaEvents = [
|
|
2162
|
+
generateDeltaEvent(10, 20), // 0
|
|
2163
|
+
generateDeltaEvent(20, 30), // 1
|
|
2164
|
+
generateDeltaEvent(30, 40), // 2
|
|
2165
|
+
generateDeltaEvent(40, 50), // 3
|
|
2166
|
+
generateDeltaEvent(50, 60), // 4
|
|
2167
|
+
generateDeltaEvent(60, 70), // 5
|
|
2168
|
+
generateDeltaEvent(70, 80), // 6
|
|
2169
|
+
generateDeltaEvent(80, 90), // 7
|
|
2170
|
+
generateDeltaEvent(90, 100), // 8
|
|
2171
|
+
];
|
|
2172
|
+
|
|
2173
|
+
let updateLocusInfoStub; // we use this stub to verify that an event has been fully processed
|
|
2174
|
+
let syncRequestStub;
|
|
2175
|
+
|
|
2176
|
+
beforeEach(() => {
|
|
2177
|
+
clock = sinon.useFakeTimers();
|
|
2178
|
+
|
|
2179
|
+
sinon.stub(locusInfo, 'updateParticipantDeltas');
|
|
2180
|
+
sinon.stub(locusInfo, 'updateParticipants');
|
|
2181
|
+
sinon.stub(locusInfo, 'isMeetingActive'),
|
|
2182
|
+
sinon.stub(locusInfo, 'handleOneOnOneEvent'),
|
|
2183
|
+
|
|
2184
|
+
updateLocusInfoStub = sinon.stub(locusInfo, 'updateLocusInfo');
|
|
2185
|
+
syncRequestStub = sinon.stub().resolves({body: {}});
|
|
2186
|
+
|
|
2187
|
+
mockMeeting.locusInfo = locusInfo;
|
|
2188
|
+
mockMeeting.locusUrl = 'fake locus url';
|
|
2189
|
+
mockMeeting.meetingRequest = {
|
|
2190
|
+
getLocusDTO: syncRequestStub,
|
|
2191
|
+
};
|
|
2192
|
+
|
|
2193
|
+
locusInfo.onFullLocus({
|
|
2194
|
+
sequence: {
|
|
2195
|
+
rangeStart: 0,
|
|
2196
|
+
rangeEnd: 0,
|
|
2197
|
+
entries: [10]
|
|
2198
|
+
},
|
|
2199
|
+
self: {
|
|
2200
|
+
person: {
|
|
2201
|
+
id: 'test person id'
|
|
2202
|
+
}
|
|
2203
|
+
},
|
|
2204
|
+
});
|
|
2205
|
+
|
|
2206
|
+
updateLocusInfoStub.resetHistory();
|
|
2207
|
+
});
|
|
2208
|
+
|
|
2209
|
+
afterEach(() => {
|
|
2210
|
+
clock.restore();
|
|
2211
|
+
});
|
|
2212
|
+
|
|
2213
|
+
it('queues out-of-order deltas until it receives a correct delta', () => {
|
|
2214
|
+
// send some out-of-order deltas
|
|
2215
|
+
locusInfo.handleLocusDelta(deltaEvents[1], mockMeeting);
|
|
2216
|
+
locusInfo.handleLocusDelta(deltaEvents[4], mockMeeting);
|
|
2217
|
+
|
|
2218
|
+
// they should be queued and not processed
|
|
2219
|
+
assert.notCalled(updateLocusInfoStub);
|
|
2220
|
+
|
|
2221
|
+
// now one of the missing ones, but not the one SDK is really waiting for
|
|
2222
|
+
locusInfo.handleLocusDelta(deltaEvents[2], mockMeeting);
|
|
2223
|
+
|
|
2224
|
+
// still nothing should be processed
|
|
2225
|
+
assert.notCalled(updateLocusInfoStub);
|
|
2226
|
+
|
|
2227
|
+
// now send the one SDK is waiting for
|
|
2228
|
+
locusInfo.handleLocusDelta(deltaEvents[0], mockMeeting);
|
|
2229
|
+
|
|
2230
|
+
// so deltaEvents with indexes 1,2,3 can be processed, but 5 still not, because 4 is missing
|
|
2231
|
+
assert.callCount(updateLocusInfoStub, 3);
|
|
2232
|
+
assert.calledWith(updateLocusInfoStub.getCall(0), deltaEvents[0]);
|
|
2233
|
+
assert.calledWith(updateLocusInfoStub.getCall(1), deltaEvents[1]);
|
|
2234
|
+
assert.calledWith(updateLocusInfoStub.getCall(2), deltaEvents[2]);
|
|
2235
|
+
|
|
2236
|
+
updateLocusInfoStub.resetHistory();
|
|
2237
|
+
|
|
2238
|
+
// now send deltaEvents[4]
|
|
2239
|
+
locusInfo.handleLocusDelta(deltaEvents[3], mockMeeting);
|
|
2240
|
+
|
|
2241
|
+
// and verify deltaEvents[4] and deltaEvents[5] have been processed
|
|
2242
|
+
assert.callCount(updateLocusInfoStub, 2);
|
|
2243
|
+
assert.calledWith(updateLocusInfoStub.getCall(0), deltaEvents[3]);
|
|
2244
|
+
assert.calledWith(updateLocusInfoStub.getCall(1), deltaEvents[4]);
|
|
2245
|
+
});
|
|
2246
|
+
|
|
2247
|
+
it('handles out-of-order deltas correctly even if all arrive in reverse order', () => {
|
|
2248
|
+
// send a bunch deltas in reverse order
|
|
2249
|
+
for(let i = 4; i >= 0; i--) {
|
|
2250
|
+
locusInfo.handleLocusDelta(deltaEvents[i], mockMeeting);
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
// they should be queued and then processed in correct order
|
|
2254
|
+
assert.callCount(updateLocusInfoStub, 5);
|
|
2255
|
+
assert.calledWith(updateLocusInfoStub.getCall(0), deltaEvents[0]);
|
|
2256
|
+
assert.calledWith(updateLocusInfoStub.getCall(1), deltaEvents[1]);
|
|
2257
|
+
assert.calledWith(updateLocusInfoStub.getCall(2), deltaEvents[2]);
|
|
2258
|
+
assert.calledWith(updateLocusInfoStub.getCall(3), deltaEvents[3]);
|
|
2259
|
+
assert.calledWith(updateLocusInfoStub.getCall(4), deltaEvents[4]);
|
|
2260
|
+
});
|
|
2261
|
+
|
|
2262
|
+
it('sends a sync request using syncUrl if it receives at least 1 delta event and processes later deltas after sync correctly', async () => {
|
|
2263
|
+
// the test first sends an initial "good" delta
|
|
2264
|
+
const initialDeltaIdx = 0;
|
|
2265
|
+
const initialDelta = deltaEvents[initialDeltaIdx];
|
|
2266
|
+
|
|
2267
|
+
// then it sends a bunch of out-of-order deltas (at least 6 to trigger a sync), last one being lastOooDelta
|
|
2268
|
+
const firstOooDeltaIdx = 2;
|
|
2269
|
+
const lastOooDeltaIdx = 7;
|
|
2270
|
+
const lastOooDelta = deltaEvents[lastOooDeltaIdx];
|
|
2271
|
+
|
|
2272
|
+
// and finally, after the sync it sends another "good" delta
|
|
2273
|
+
const goodDeltaAfterSync = deltaEvents[8];
|
|
2274
|
+
|
|
2275
|
+
const deltaLocusFromSyncResponse = {
|
|
2276
|
+
baseSequence: {
|
|
2277
|
+
rangeStart: 0,
|
|
2278
|
+
rangeEnd: 0,
|
|
2279
|
+
entries: [initialDelta.sequence.entries[0]]
|
|
2280
|
+
},
|
|
2281
|
+
sequence: {
|
|
2282
|
+
rangeStart: 0,
|
|
2283
|
+
rangeEnd: 0,
|
|
2284
|
+
entries: [lastOooDelta.sequence.entries[0]]
|
|
2285
|
+
},
|
|
2286
|
+
syncUrl: `fake sync url for sequence ${lastOooDelta.sequence.entries[0]}`,
|
|
2287
|
+
self: {
|
|
2288
|
+
person: {
|
|
2289
|
+
id: 'test person id'
|
|
2290
|
+
}
|
|
2291
|
+
},
|
|
2292
|
+
};
|
|
2293
|
+
|
|
2294
|
+
syncRequestStub.resolves({
|
|
2295
|
+
body: deltaLocusFromSyncResponse
|
|
2296
|
+
});
|
|
2297
|
+
|
|
2298
|
+
// send one correct delta so that SDK has the syncUrl
|
|
2299
|
+
locusInfo.handleLocusDelta(initialDelta, mockMeeting);
|
|
2300
|
+
|
|
2301
|
+
updateLocusInfoStub.resetHistory();
|
|
2302
|
+
|
|
2303
|
+
// send 6 out-of-order deltas to trigger a sync (we're skipping deltaEvents[1])
|
|
2304
|
+
for(let i = firstOooDeltaIdx; i <= lastOooDeltaIdx; i++) {
|
|
2305
|
+
locusInfo.handleLocusDelta(deltaEvents[i], mockMeeting);
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2308
|
+
await testUtils.flushPromises();
|
|
2309
|
+
|
|
2310
|
+
// check that sync was done using the correct syncUrl
|
|
2311
|
+
assert.calledOnceWithExactly(syncRequestStub, {url: initialDelta.syncUrl});
|
|
2312
|
+
assert.calledOnceWithExactly(updateLocusInfoStub, deltaLocusFromSyncResponse);
|
|
2313
|
+
|
|
2314
|
+
updateLocusInfoStub.resetHistory();
|
|
2315
|
+
|
|
2316
|
+
// now send another delta - a good one, it should be processed as normal
|
|
2317
|
+
locusInfo.handleLocusDelta(goodDeltaAfterSync, mockMeeting);
|
|
2318
|
+
|
|
2319
|
+
assert.calledOnceWithExactly(updateLocusInfoStub, goodDeltaAfterSync);
|
|
2320
|
+
});
|
|
2321
|
+
|
|
2322
|
+
it('does a sync if blocked on out-of-order deltas for too long', async () => {
|
|
2323
|
+
// stub random so that the timer fires after 12500 ms
|
|
2324
|
+
sinon.stub(Math, 'random').returns(0.5);
|
|
2325
|
+
|
|
2326
|
+
const oooDelta = deltaEvents[3];
|
|
2327
|
+
|
|
2328
|
+
// setup the stubs so that the sync request receives a full DTO with the sequence equal to the out-of-order delta we simulate
|
|
2329
|
+
const fullLocus = {
|
|
2330
|
+
sequence: oooDelta.sequence
|
|
2331
|
+
};
|
|
2332
|
+
syncRequestStub.resolves({
|
|
2333
|
+
body: fullLocus
|
|
2334
|
+
});
|
|
2335
|
+
|
|
2336
|
+
// send an out-of-order delta
|
|
2337
|
+
locusInfo.handleLocusDelta(oooDelta, mockMeeting);
|
|
2338
|
+
|
|
2339
|
+
await clock.tickAsync(12499);
|
|
2340
|
+
await testUtils.flushPromises();
|
|
2341
|
+
assert.notCalled(syncRequestStub);
|
|
2342
|
+
assert.notCalled(updateLocusInfoStub);
|
|
2343
|
+
|
|
2344
|
+
await clock.tickAsync(1);
|
|
2345
|
+
await testUtils.flushPromises();
|
|
2346
|
+
|
|
2347
|
+
assert.calledOnceWithExactly(syncRequestStub, {url: mockMeeting.locusUrl});
|
|
2348
|
+
assert.calledOnceWithExactly(updateLocusInfoStub, fullLocus);
|
|
2349
|
+
});
|
|
2350
|
+
|
|
2351
|
+
it('does a sync if out-of-order deltas queue becomes too big', async () => {
|
|
2352
|
+
// setup the stubs so that the sync request receives a full DTO with the sequence equal to the out-of-order delta we simulate
|
|
2353
|
+
const fullLocus = {
|
|
2354
|
+
sequence: deltaEvents[6].sequence
|
|
2355
|
+
};
|
|
2356
|
+
syncRequestStub.resolves({
|
|
2357
|
+
body: fullLocus
|
|
2358
|
+
});
|
|
2359
|
+
|
|
2360
|
+
// send 5 deltas, starting from deltaEvents[1] so that SDK is blocked waiting for deltaEvents[0]
|
|
2361
|
+
for(let i = 0; i < 5; i++) {
|
|
2362
|
+
locusInfo.handleLocusDelta(deltaEvents[i + 1], mockMeeting);
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
// nothing should happen, SDK should still be waiting for deltaEvents[0]
|
|
2366
|
+
assert.notCalled(syncRequestStub);
|
|
2367
|
+
assert.notCalled(updateLocusInfoStub);
|
|
2368
|
+
|
|
2369
|
+
// now send one more out-of-order delta to trigger a sync request
|
|
2370
|
+
locusInfo.handleLocusDelta(deltaEvents[6], mockMeeting);
|
|
2371
|
+
|
|
2372
|
+
await testUtils.flushPromises();
|
|
2373
|
+
|
|
2374
|
+
// check sync was done
|
|
2375
|
+
assert.calledOnceWithExactly(syncRequestStub, {url: mockMeeting.locusUrl});
|
|
2376
|
+
assert.calledOnceWithExactly(updateLocusInfoStub, fullLocus);
|
|
2377
|
+
});
|
|
2378
|
+
|
|
2379
|
+
it('processes delta events that are not included in sync response', async () => {
|
|
2380
|
+
// this test sends a bunch of out-of-order deltas, this triggers a sync
|
|
2381
|
+
// but the full locus response doesn't include the last 2 deltas received, so
|
|
2382
|
+
// we check that these 2 deltas are also processed after sync response
|
|
2383
|
+
const fullLocusFromSyncResponse = {
|
|
2384
|
+
baseSequence: {
|
|
2385
|
+
rangeStart: 0,
|
|
2386
|
+
rangeEnd: 0,
|
|
2387
|
+
entries: [deltaEvents[0].sequence.entries[0]]
|
|
2388
|
+
},
|
|
2389
|
+
sequence: {
|
|
2390
|
+
rangeStart: 0,
|
|
2391
|
+
rangeEnd: 0,
|
|
2392
|
+
entries: [deltaEvents[5].sequence.entries[0]]
|
|
2393
|
+
},
|
|
2394
|
+
syncUrl: `fake sync url for sequence ${deltaEvents[5].sequence.entries[0]}`,
|
|
2395
|
+
self: {
|
|
2396
|
+
person: {
|
|
2397
|
+
id: 'test person id'
|
|
2398
|
+
}
|
|
2399
|
+
},
|
|
2400
|
+
};
|
|
2401
|
+
|
|
2402
|
+
syncRequestStub.resolves({
|
|
2403
|
+
body: fullLocusFromSyncResponse
|
|
2404
|
+
});
|
|
2405
|
+
|
|
2406
|
+
// send at least 6 out-of-order deltas to trigger a sync (we're skipping deltaEvents[0])
|
|
2407
|
+
for(let i = 1; i <= 7; i++) {
|
|
2408
|
+
locusInfo.handleLocusDelta(deltaEvents[i], mockMeeting);
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2411
|
+
await testUtils.flushPromises();
|
|
2412
|
+
|
|
2413
|
+
// check that sync was done
|
|
2414
|
+
assert.calledOnceWithExactly(syncRequestStub, {url: mockMeeting.locusUrl});
|
|
2415
|
+
|
|
2416
|
+
// and that remaining deltas from the queue that were not included in full Locus were also processed
|
|
2417
|
+
assert.callCount(updateLocusInfoStub, 3);
|
|
2418
|
+
assert.calledWith(updateLocusInfoStub.getCall(0), fullLocusFromSyncResponse);
|
|
2419
|
+
assert.calledWith(updateLocusInfoStub.getCall(1), deltaEvents[6]);
|
|
2420
|
+
assert.calledWith(updateLocusInfoStub.getCall(2), deltaEvents[7]);
|
|
2421
|
+
});
|
|
2422
|
+
});
|
|
2086
2423
|
});
|
|
2087
2424
|
});
|
|
@@ -334,27 +334,5 @@ describe('locus-info/parser', () => {
|
|
|
334
334
|
|
|
335
335
|
assert.isFalse(result);
|
|
336
336
|
});
|
|
337
|
-
|
|
338
|
-
it('sets parser status to IDLE if workingCopy is invalid', () => {
|
|
339
|
-
const {IDLE, WORKING} = LocusDeltaParser.status;
|
|
340
|
-
|
|
341
|
-
parser.workingCopy = null;
|
|
342
|
-
parser.status = WORKING;
|
|
343
|
-
|
|
344
|
-
parser.isValidLocus(loci);
|
|
345
|
-
|
|
346
|
-
assert.equal(parser.status, IDLE);
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
it('sets parser status to IDLE if new loci is invalid', () => {
|
|
350
|
-
const {IDLE, WORKING} = LocusDeltaParser.status;
|
|
351
|
-
|
|
352
|
-
parser.workingCopy = loci;
|
|
353
|
-
parser.status = WORKING;
|
|
354
|
-
|
|
355
|
-
parser.isValidLocus(null);
|
|
356
|
-
|
|
357
|
-
assert.equal(parser.status, IDLE);
|
|
358
|
-
});
|
|
359
337
|
});
|
|
360
338
|
});
|
|
@@ -179,10 +179,10 @@ describe('plugin-meetings', () => {
|
|
|
179
179
|
});
|
|
180
180
|
|
|
181
181
|
describe('updateLocusWithDelta', () => {
|
|
182
|
-
it('should call
|
|
182
|
+
it('should call handleLocusDelta with the new delta locus', () => {
|
|
183
183
|
const meeting = {
|
|
184
184
|
locusInfo: {
|
|
185
|
-
|
|
185
|
+
handleLocusDelta: sinon.stub()
|
|
186
186
|
},
|
|
187
187
|
};
|
|
188
188
|
|
|
@@ -195,13 +195,13 @@ describe('plugin-meetings', () => {
|
|
|
195
195
|
const response = MeetingUtil.updateLocusWithDelta(meeting, originalResponse);
|
|
196
196
|
|
|
197
197
|
assert.deepEqual(response, originalResponse);
|
|
198
|
-
assert.calledOnceWithExactly(meeting.locusInfo.
|
|
198
|
+
assert.calledOnceWithExactly(meeting.locusInfo.handleLocusDelta, 'locus', meeting);
|
|
199
199
|
});
|
|
200
200
|
|
|
201
201
|
it('should handle locus being missing from the response', () => {
|
|
202
202
|
const meeting = {
|
|
203
203
|
locusInfo: {
|
|
204
|
-
|
|
204
|
+
handleLocusDelta: sinon.stub(),
|
|
205
205
|
},
|
|
206
206
|
};
|
|
207
207
|
|
|
@@ -212,7 +212,7 @@ describe('plugin-meetings', () => {
|
|
|
212
212
|
const response = MeetingUtil.updateLocusWithDelta(meeting, originalResponse);
|
|
213
213
|
|
|
214
214
|
assert.deepEqual(response, originalResponse);
|
|
215
|
-
assert.notCalled(meeting.locusInfo.
|
|
215
|
+
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
|
216
216
|
});
|
|
217
217
|
|
|
218
218
|
it('should work with an undefined meeting', () => {
|