Fix instantly sending RRs
Splits UserActivity into a tristate of 'active' (last < 1s), 'passive' (lasts a couple of mins) and neither. Read receipts are sent when 'active', read markers are sent while 'passive'. Also fixed a document / window mix-up on the 'blur' handler. Also adds a unit test for UserActivity because it's quite complex now (and changes UserActivity to make it testable by accessing the singleton via sharedInstance() rather than exporting it directly). Fixes https://github.com/vector-im/riot-web/issues/9023
This commit is contained in:
parent
2e081982ee
commit
ce1623691e
4 changed files with 250 additions and 51 deletions
134
test/UserActivity-test.js
Normal file
134
test/UserActivity-test.js
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
Copyright 2019 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import expect from 'expect';
|
||||
import lolex from 'lolex';
|
||||
import jest from 'jest-mock';
|
||||
import EventEmitter from 'events';
|
||||
import UserActivity from '../src/UserActivity';
|
||||
|
||||
class FakeDomEventEmitter extends EventEmitter {
|
||||
addEventListener(what, l) {
|
||||
this.on(what, l);
|
||||
}
|
||||
|
||||
removeEventListener(what, l) {
|
||||
this.removeListener(what, l);
|
||||
}
|
||||
};
|
||||
|
||||
describe('UserActivity', function() {
|
||||
let fakeWindow;
|
||||
let fakeDocument;
|
||||
let userActivity;
|
||||
let clock;
|
||||
|
||||
beforeEach(function() {
|
||||
fakeWindow = new FakeDomEventEmitter(),
|
||||
fakeDocument = new FakeDomEventEmitter(),
|
||||
userActivity = new UserActivity(fakeWindow, fakeDocument);
|
||||
userActivity.start();
|
||||
clock = lolex.install();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
userActivity.stop();
|
||||
userActivity = null;
|
||||
clock.uninstall();
|
||||
clock = null;
|
||||
});
|
||||
|
||||
it('should return the same shared instance', function() {
|
||||
expect(UserActivity.sharedInstance()).toBe(UserActivity.sharedInstance());
|
||||
});
|
||||
|
||||
it('should consider user inactive if no activity', function() {
|
||||
expect(userActivity.userCurrentlyActive()).toBe(false);
|
||||
});
|
||||
|
||||
it('should consider user not passive if no activity', function() {
|
||||
expect(userActivity.userCurrentlyPassive()).toBe(false);
|
||||
});
|
||||
|
||||
it('should not consider user active after activity if no window focus', function() {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(false);
|
||||
|
||||
userActivity._onUserActivity({});
|
||||
expect(userActivity.userCurrentlyActive()).toBe(false);
|
||||
expect(userActivity.userCurrentlyPassive()).toBe(false);
|
||||
});
|
||||
|
||||
it('should consider user active shortly after activity', function() {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity._onUserActivity({});
|
||||
expect(userActivity.userCurrentlyActive()).toBe(true);
|
||||
expect(userActivity.userCurrentlyPassive()).toBe(true);
|
||||
clock.tick(200);
|
||||
expect(userActivity.userCurrentlyActive()).toBe(true);
|
||||
expect(userActivity.userCurrentlyPassive()).toBe(true);
|
||||
});
|
||||
|
||||
it('should consider user not active after 10s of no activity', function() {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity._onUserActivity({});
|
||||
clock.tick(10000);
|
||||
expect(userActivity.userCurrentlyActive()).toBe(false);
|
||||
});
|
||||
|
||||
it('should consider user passive after 10s of no activity', function() {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity._onUserActivity({});
|
||||
clock.tick(10000);
|
||||
expect(userActivity.userCurrentlyPassive()).toBe(true);
|
||||
});
|
||||
|
||||
it('should not consider user passive after 10s if window un-focused', function() {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity._onUserActivity({});
|
||||
clock.tick(10000);
|
||||
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(false);
|
||||
fakeWindow.emit('blur', {});
|
||||
|
||||
expect(userActivity.userCurrentlyPassive()).toBe(false);
|
||||
});
|
||||
|
||||
it('should not consider user passive after 3 mins', function() {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity._onUserActivity({});
|
||||
clock.tick(3 * 60 * 1000);
|
||||
|
||||
expect(userActivity.userCurrentlyPassive()).toBe(false);
|
||||
});
|
||||
|
||||
it('should extend timer on activity', function() {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity._onUserActivity({});
|
||||
clock.tick(1 * 60 * 1000);
|
||||
userActivity._onUserActivity({});
|
||||
clock.tick(1 * 60 * 1000);
|
||||
userActivity._onUserActivity({});
|
||||
clock.tick(1 * 60 * 1000);
|
||||
|
||||
expect(userActivity.userCurrentlyPassive()).toBe(true);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue