Skip to content

Commit c617976

Browse files
committed
test: added tests for RingBuffer & sogsRollingDeletions
1 parent ad03fbd commit c617976

File tree

5 files changed

+209
-8
lines changed

5 files changed

+209
-8
lines changed

ts/session/apis/open_group_api/sogsv3/sogsRollingDeletions.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { RingBuffer } from '../../../utils/RingBuffer';
22

33
const rollingDeletedMessageIds: Map<string, RingBuffer<number>> = new Map();
44

5-
// keep 2000 deleted message ids in memory
6-
const perRoomRollingRemovedIds = 2000;
7-
85
const addMessageDeletedId = (conversationId: string, messageDeletedId: number) => {
96
if (!rollingDeletedMessageIds.has(conversationId)) {
10-
rollingDeletedMessageIds.set(conversationId, new RingBuffer<number>(perRoomRollingRemovedIds));
7+
rollingDeletedMessageIds.set(
8+
conversationId,
9+
new RingBuffer<number>(sogsRollingDeletions.getPerRoomCount())
10+
);
1111
}
1212
const ringBuffer = rollingDeletedMessageIds.get(conversationId);
1313
if (!ringBuffer) {
@@ -16,7 +16,6 @@ const addMessageDeletedId = (conversationId: string, messageDeletedId: number) =
1616
ringBuffer.add(messageDeletedId);
1717
};
1818

19-
2019
const hasMessageDeletedId = (conversationId: string, messageDeletedId: number) => {
2120
if (!rollingDeletedMessageIds.has(conversationId)) {
2221
return false;
@@ -29,4 +28,21 @@ const hasMessageDeletedId = (conversationId: string, messageDeletedId: number) =
2928
return messageIdWasDeletedRecently;
3029
};
3130

32-
export const sogsRollingDeletions = { addMessageDeletedId, hasMessageDeletedId };
31+
/**
32+
* emptyMessageDeleteIds should only be used for testing purposes.
33+
*/
34+
const emptyMessageDeleteIds = () => {
35+
rollingDeletedMessageIds.clear();
36+
};
37+
38+
export const sogsRollingDeletions = {
39+
addMessageDeletedId,
40+
hasMessageDeletedId,
41+
emptyMessageDeleteIds,
42+
getPerRoomCount,
43+
};
44+
45+
// keep 2000 deleted message ids in memory
46+
function getPerRoomCount() {
47+
return 2000;
48+
}

ts/session/apis/open_group_api/sogsv3/sogsV3BatchPoll.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,7 @@ const makeBatchRequestPayload = (
241241
method: 'GET',
242242
path: isNumber(options.messages.sinceSeqNo)
243243
? `/room/${options.messages.roomId}/messages/since/${options.messages.sinceSeqNo}?t=r&reactors=${Reactions.SOGSReactorsFetchCount}`
244-
: // : `/room/${options.messages.roomId}/messages/since/180000?t=r&reactors=${Reactions.SOGSReactorsFetchCount}`,
245-
`/room/${options.messages.roomId}/messages/recent?reactors=${Reactions.SOGSReactorsFetchCount}`,
244+
: `/room/${options.messages.roomId}/messages/recent?reactors=${Reactions.SOGSReactorsFetchCount}`,
246245
};
247246
}
248247
break;

ts/session/utils/RingBuffer.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* This ringbuffer class can be used to keep a list of at most a size and removing old items first when the size is exceeded.
3+
* Internally, it uses an array to keep track of the order, so two times the same item can exist in it.
4+
*
5+
*/
16
export class RingBuffer<T> {
27
private buffer: Array<T> = [];
38
private readonly capacity: number;
@@ -10,6 +15,10 @@ export class RingBuffer<T> {
1015
return this.capacity;
1116
}
1217

18+
public getLength(): number {
19+
return this.buffer.length;
20+
}
21+
1322
public add(item: T) {
1423
this.buffer.push(item);
1524
this.crop();
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { expect } from 'chai';
2+
import Sinon from 'sinon';
3+
import { sogsRollingDeletions } from '../../../../session/apis/open_group_api/sogsv3/sogsRollingDeletions';
4+
5+
describe('sogsRollingDeletions', () => {
6+
beforeEach(() => {
7+
sogsRollingDeletions.emptyMessageDeleteIds();
8+
Sinon.stub(sogsRollingDeletions, 'getPerRoomCount').returns(5);
9+
});
10+
11+
afterEach(() => {
12+
Sinon.restore();
13+
});
14+
15+
it('no items at all returns false', () => {
16+
expect(sogsRollingDeletions.hasMessageDeletedId('convo1', 1)).to.be.equal(
17+
false,
18+
'1 should not be there'
19+
);
20+
});
21+
22+
it('no items in that convo returns false', () => {
23+
sogsRollingDeletions.addMessageDeletedId('convo1', 1);
24+
25+
expect(sogsRollingDeletions.hasMessageDeletedId('convo2', 1)).to.be.equal(
26+
false,
27+
'1 should not be there'
28+
);
29+
});
30+
31+
it('can add 1 item', () => {
32+
sogsRollingDeletions.addMessageDeletedId('convo1', 1);
33+
expect(sogsRollingDeletions.hasMessageDeletedId('convo1', 1)).to.be.equal(
34+
true,
35+
'1 should be there'
36+
);
37+
});
38+
39+
it('can add more than capacity items', () => {
40+
sogsRollingDeletions.addMessageDeletedId('convo1', 1);
41+
sogsRollingDeletions.addMessageDeletedId('convo1', 2);
42+
sogsRollingDeletions.addMessageDeletedId('convo1', 3);
43+
sogsRollingDeletions.addMessageDeletedId('convo1', 4);
44+
sogsRollingDeletions.addMessageDeletedId('convo1', 5);
45+
sogsRollingDeletions.addMessageDeletedId('convo1', 6);
46+
expect(sogsRollingDeletions.hasMessageDeletedId('convo1', 1)).to.be.equal(
47+
false,
48+
'1 should not be there'
49+
);
50+
expect(sogsRollingDeletions.hasMessageDeletedId('convo1', 2)).to.be.equal(
51+
true,
52+
'2 should be there'
53+
);
54+
expect(sogsRollingDeletions.hasMessageDeletedId('convo1', 3)).to.be.equal(
55+
true,
56+
'3 should be there'
57+
);
58+
expect(sogsRollingDeletions.hasMessageDeletedId('convo1', 4)).to.be.equal(
59+
true,
60+
'4 should be there'
61+
);
62+
expect(sogsRollingDeletions.hasMessageDeletedId('convo1', 5)).to.be.equal(
63+
true,
64+
'5 should be there'
65+
);
66+
expect(sogsRollingDeletions.hasMessageDeletedId('convo1', 6)).to.be.equal(
67+
true,
68+
'6 should be there'
69+
);
70+
});
71+
});
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// tslint:disable: no-implicit-dependencies max-func-body-length no-unused-expression no-require-imports no-var-requires
2+
3+
import chai from 'chai';
4+
import { RingBuffer } from '../../../../session/utils/RingBuffer';
5+
6+
const { expect } = chai;
7+
8+
describe('RingBuffer Utils', () => {
9+
it('gets created with right capacity', () => {
10+
const ring = new RingBuffer<number>(5000);
11+
expect(ring.getCapacity()).to.equal(5000);
12+
expect(ring.getLength()).to.equal(0);
13+
expect(ring.has(0)).to.equal(false, '4 should not be there');
14+
});
15+
16+
describe('length & capacity are right', () => {
17+
it('length is right 1', () => {
18+
const ring = new RingBuffer<number>(4);
19+
ring.add(0);
20+
expect(ring.getLength()).to.equal(1);
21+
});
22+
23+
it('length is right 4', () => {
24+
const ring = new RingBuffer<number>(4);
25+
ring.add(0);
26+
ring.add(1);
27+
ring.add(2);
28+
ring.add(3);
29+
expect(ring.getLength()).to.equal(4);
30+
});
31+
32+
it('capacity does not get exceeded', () => {
33+
const ring = new RingBuffer<number>(4);
34+
ring.add(0);
35+
ring.add(1);
36+
ring.add(2);
37+
ring.add(3);
38+
ring.add(4);
39+
expect(ring.getLength()).to.equal(4);
40+
});
41+
});
42+
43+
it('items are removed in order 1', () => {
44+
const ring = new RingBuffer<number>(4);
45+
ring.add(0);
46+
ring.add(1);
47+
ring.add(2);
48+
ring.add(3);
49+
ring.add(4);
50+
expect(ring.has(0)).to.equal(false, '0 should not be there anymore');
51+
expect(ring.has(1)).to.equal(true, '1 should still be there');
52+
expect(ring.has(2)).to.equal(true, '2 should still be there');
53+
expect(ring.has(3)).to.equal(true, '3 should still be there');
54+
expect(ring.has(4)).to.equal(true, '4 should still be there');
55+
});
56+
57+
it('two times the same items can exist', () => {
58+
const ring = new RingBuffer<number>(4);
59+
ring.add(0);
60+
ring.add(1);
61+
ring.add(2);
62+
ring.add(1);
63+
ring.add(4);
64+
expect(ring.has(0)).to.equal(false, '0 should not be there anymore');
65+
expect(ring.has(1)).to.equal(true, '1 should still be there');
66+
expect(ring.has(2)).to.equal(true, '2 should still be there');
67+
expect(ring.has(3)).to.equal(false, '3 should not be there');
68+
expect(ring.has(4)).to.equal(true, '4 should still be there');
69+
});
70+
71+
it('items are removed in order completely', () => {
72+
const ring = new RingBuffer<number>(4);
73+
ring.add(0);
74+
ring.add(1);
75+
ring.add(2);
76+
ring.add(3);
77+
ring.add(10);
78+
ring.add(20);
79+
ring.add(30);
80+
ring.add(40);
81+
expect(ring.has(0)).to.equal(false, '0 should not be there anymore');
82+
expect(ring.has(1)).to.equal(false, '1 should not be there');
83+
expect(ring.has(2)).to.equal(false, '2 should not be there');
84+
expect(ring.has(3)).to.equal(false, '3 should not be there');
85+
expect(ring.has(4)).to.equal(false, '4 should not be there');
86+
87+
expect(ring.has(10)).to.equal(true, '10 should still be there');
88+
expect(ring.has(20)).to.equal(true, '20 should still be there');
89+
expect(ring.has(30)).to.equal(true, '30 should still be there');
90+
expect(ring.has(40)).to.equal(true, '40 should still be there');
91+
});
92+
93+
it('clear empties the list but keeps the capacity', () => {
94+
const ring = new RingBuffer<number>(4);
95+
ring.add(0);
96+
ring.add(1);
97+
ring.add(2);
98+
ring.add(1);
99+
expect(ring.getLength()).to.equal(4);
100+
expect(ring.getCapacity()).to.equal(4);
101+
ring.clear();
102+
expect(ring.getCapacity()).to.equal(4);
103+
104+
expect(ring.getLength()).to.equal(0);
105+
});
106+
});

0 commit comments

Comments
 (0)