Gitter migration: Point people to app.gitter.im (rollout pt. 1)
[gitter.git] / public / js / utils / burst-calculator-test.js
blob3aa59bec4b545571c0dc40636eb1346f240817cf
1 'use strict';
3 const burstCalculator = require('./burst-calculator');
5 describe('burst-calculator', () => {
6   const testUserA = { id: 'abc', username: 'john_smith' };
8   it('should handle empty array', () => {
9     const result = burstCalculator.parse([]);
10     expect(result).toEqual([]);
11   });
13   it('should mark one chatItem as start of the burst', () => {
14     const chatItem = {
15       fromUser: testUserA,
16       sent: new Date()
17     };
18     const result = burstCalculator.parse([chatItem]);
19     expect(result[0]).toEqual({ burstStart: true, ...chatItem });
20   });
22   it('should group two eligible messages into a burst', () => {
23     const chatItem1 = {
24       fromUser: testUserA,
25       sent: '2020-02-04T00:00:00.000Z'
26     };
27     const chatItem2 = {
28       fromUser: testUserA,
29       sent: '2020-02-04T00:01:00.000Z'
30     };
31     const result = burstCalculator.parse([chatItem1, chatItem2]);
32     expect(result[0]).toEqual({ burstStart: true, ...chatItem1 });
33     expect(result[1]).toEqual({ burstStart: false, ...chatItem2 });
34   });
36   it('should reset burst with a status message', () => {
37     const chatItem1 = {
38       fromUser: testUserA,
39       sent: '2020-02-04T00:00:00.000Z'
40     };
41     const chatItem2 = {
42       status: true,
43       fromUser: testUserA,
44       sent: '2020-02-04T00:01:00.000Z'
45     };
46     const result = burstCalculator.parse([chatItem1, chatItem2]);
47     expect(result[0]).toEqual({ burstStart: true, ...chatItem1 });
48     expect(result[1]).toEqual({ burstStart: true, ...chatItem2 });
49   });
51   it('should reset burst with a different user', () => {
52     const testUserB = { id: 'def', username: 'peter_griffin' };
53     const chatItem1 = {
54       fromUser: testUserA,
55       sent: '2020-02-04T00:00:00.000Z'
56     };
57     const chatItem2 = {
58       fromUser: testUserB,
59       sent: '2020-02-04T00:01:00.000Z'
60     };
61     const result = burstCalculator.parse([chatItem1, chatItem2]);
62     expect(result[0]).toEqual({ burstStart: true, ...chatItem1 });
63     expect(result[1]).toEqual({ burstStart: true, ...chatItem2 });
64   });
66   it('should reset burst when more than 5 minutes elapses from the burst start', () => {
67     const chatItem1 = {
68       fromUser: testUserA,
69       sent: '2020-02-04T00:00:00.000Z'
70     };
71     const chatItem2 = {
72       fromUser: testUserA,
73       sent: '2020-02-04T00:02:00.000Z'
74     };
75     // 4 minutes since the last message, this would discover an issue if we only
76     // measured 5 minutes since the previous message
77     const chatItem3 = {
78       fromUser: testUserA,
79       sent: '2020-02-04T00:06:00.000Z'
80     };
81     const result = burstCalculator.parse([chatItem1, chatItem2, chatItem3]);
82     expect(result[0]).toEqual({ burstStart: true, ...chatItem1 });
83     expect(result[1]).toEqual({ burstStart: false, ...chatItem2 });
84     expect(result[2]).toEqual({ burstStart: true, ...chatItem3 });
85   });
87   describe('thread messages', () => {
88     it('should ignore thread messages and compute burst only for MMF', () => {
89       const chatItem1 = {
90         fromUser: testUserA,
91         sent: '2020-02-04T00:00:00.000Z'
92       };
93       // this message will get ignored and no burst attribute is added
94       const chatItem2 = {
95         parentId: 'xyz',
96         fromUser: testUserA,
97         sent: '2020-02-04T00:01:00.000Z'
98       };
99       // this message continues the burst in main message feed
100       const chatItem3 = {
101         fromUser: testUserA,
102         sent: '2020-02-04T00:02:00.000Z'
103       };
104       const result = burstCalculator.parse([chatItem1, chatItem2, chatItem3]);
105       expect(result[0]).toEqual({ burstStart: true, ...chatItem1 });
106       expect(result[1]).toEqual({ ...chatItem2 });
107       expect(result[2]).toEqual({ burstStart: false, ...chatItem3 });
108     });
110     it('should ignore thread messages and only reset burst if MMF chat message users differ', () => {
111       const testUserB = { id: 'def', username: 'peter_griffin' };
112       const chatItem1 = {
113         fromUser: testUserA,
114         sent: '2020-02-04T00:00:00.000Z'
115       };
116       // this message will get ignored and no burst attribute is added
117       const chatItem2 = {
118         parentId: 'xyz',
119         fromUser: testUserB,
120         sent: '2020-02-04T00:01:00.000Z'
121       };
122       // this message restarts the burst in main message feed, we validate that we don't continue burst from the previous thread message
123       const chatItem3 = {
124         fromUser: testUserB,
125         sent: '2020-02-04T00:02:00.000Z'
126       };
127       const result = burstCalculator.parse([chatItem1, chatItem2, chatItem3]);
128       expect(result[0]).toEqual({ burstStart: true, ...chatItem1 });
129       expect(result[1]).toEqual({ ...chatItem2 });
130       expect(result[2]).toEqual({ burstStart: true, ...chatItem3 });
131     });
132   });
134   describe('complex sanity check scenarios', () => {
135     const testUserB = { id: 'def', username: 'peter_griffin' };
137     const baseTimeAddMinutes = minutes => {
138       const base = new Date('2020-02-04T00:00:00.000Z');
139       base.setMinutes(minutes);
140       return base.toISOString();
141     };
143     const removeBurstDataForTesting = items =>
144       items.map(item => {
145         const newItem = { ...item };
146         delete newItem.burstStart;
147         return newItem;
148       });
150     it('should calculate bursts for multiple messages', () => {
151       const expected = [
152         {
153           fromUser: testUserA,
154           sent: baseTimeAddMinutes(0),
155           burstStart: true
156         },
157         // reset burst, different user
158         {
159           fromUser: testUserB,
160           sent: baseTimeAddMinutes(1),
161           burstStart: true
162         },
163         // continue burst
164         {
165           fromUser: testUserB,
166           sent: baseTimeAddMinutes(2),
167           burstStart: false
168         },
169         //reset burst status
170         {
171           fromUser: testUserB,
172           sent: baseTimeAddMinutes(3),
173           status: true,
174           burstStart: true
175         },
176         // reset burst, previous was status
177         {
178           fromUser: testUserB,
179           sent: baseTimeAddMinutes(4),
180           burstStart: true
181         },
182         // continue burst
183         {
184           fromUser: testUserB,
185           sent: baseTimeAddMinutes(5),
186           burstStart: false
187         }
188       ];
189       const result = burstCalculator.parse(removeBurstDataForTesting(expected));
190       expect(result).toEqual(expected);
191     });
192   });