LLS: error handling on stopping beacon (#8406)

* shared stopping error state for timeline, maxi and room warnign

Signed-off-by: Kerry Archibald <kerrya@element.io>

* check for stopping errors in roomlist share warning

Signed-off-by: Kerry Archibald <kerrya@element.io>

* lint

Signed-off-by: Kerry Archibald <kerrya@element.io>

* test stopping errors in OwnBeaconStore

Signed-off-by: Kerry Archibald <kerrya@element.io>

* update LeftPanelLiveShareWarning tests for stopping errors

Signed-off-by: Kerry Archibald <kerrya@element.io>

* reinstate try/catch for stopping beacons in create

Signed-off-by: Kerry Archibald <kerrya@element.io>

* remove unnecessary and buggy beacon stopping on creation

Signed-off-by: Kerry Archibald <kerrya@element.io>
This commit is contained in:
Kerry 2022-04-28 14:03:51 +02:00 committed by GitHub
parent 1bceeb244c
commit 472222c195
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 213 additions and 49 deletions

View file

@ -765,6 +765,64 @@ describe('OwnBeaconStore', () => {
);
});
it('records error when stopping beacon event fails to send', async () => {
jest.spyOn(logger, 'error').mockImplementation(() => {});
makeRoomsWithStateEvents([
alicesRoom1BeaconInfo,
]);
const store = await makeOwnBeaconStore();
const emitSpy = jest.spyOn(store, 'emit');
const error = new Error('oups');
mockClient.unstable_setLiveBeacon.mockRejectedValue(error);
await expect(store.stopBeacon(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).rejects.toEqual(error);
expect(store.beaconUpdateErrors.get(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).toEqual(error);
expect(emitSpy).toHaveBeenCalledWith(
OwnBeaconStoreEvent.BeaconUpdateError, getBeaconInfoIdentifier(alicesRoom1BeaconInfo), true,
);
});
it('clears previous error and emits when stopping beacon works on retry', async () => {
jest.spyOn(logger, 'error').mockImplementation(() => {});
makeRoomsWithStateEvents([
alicesRoom1BeaconInfo,
]);
const store = await makeOwnBeaconStore();
const emitSpy = jest.spyOn(store, 'emit');
const error = new Error('oups');
mockClient.unstable_setLiveBeacon.mockRejectedValueOnce(error);
await expect(store.stopBeacon(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).rejects.toEqual(error);
expect(store.beaconUpdateErrors.get(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).toEqual(error);
await store.stopBeacon(getBeaconInfoIdentifier(alicesRoom1BeaconInfo));
// error cleared
expect(store.beaconUpdateErrors.get(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).toBeFalsy();
// emit called for error clearing
expect(emitSpy).toHaveBeenCalledWith(
OwnBeaconStoreEvent.BeaconUpdateError, getBeaconInfoIdentifier(alicesRoom1BeaconInfo), false,
);
});
it('does not emit BeaconUpdateError when stopping succeeds and beacon did not have errors', async () => {
jest.spyOn(logger, 'error').mockImplementation(() => {});
makeRoomsWithStateEvents([
alicesRoom1BeaconInfo,
]);
const store = await makeOwnBeaconStore();
const emitSpy = jest.spyOn(store, 'emit');
// error cleared
expect(store.beaconUpdateErrors.get(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).toBeFalsy();
// emit called for error clearing
expect(emitSpy).not.toHaveBeenCalledWith(
OwnBeaconStoreEvent.BeaconUpdateError, getBeaconInfoIdentifier(alicesRoom1BeaconInfo), false,
);
});
it('updates beacon to live:false when it is expired but live property is true', async () => {
makeRoomsWithStateEvents([
alicesRoom1BeaconInfo,
@ -1051,6 +1109,31 @@ describe('OwnBeaconStore', () => {
);
});
it('stops publishing positions when a beacon has a stopping error', async () => {
// reject stopping beacon
const error = new Error('oups');
mockClient.unstable_setLiveBeacon.mockRejectedValue(error);
makeRoomsWithStateEvents([
alicesRoom1BeaconInfo,
]);
const store = await makeOwnBeaconStore();
// wait for store to settle
await flushPromisesWithFakeTimers();
// 2 positions from watchPosition in this period
await advanceAndFlushPromises(5000);
// attempt to stop the beacon
await expect(store.stopBeacon(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).rejects.toEqual(error);
expect(store.beaconUpdateErrors.get(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).toEqual(error);
// 2 more positions in this period
await advanceAndFlushPromises(50000);
// only two positions pre-stopping were sent
expect(mockClient.sendEvent).toHaveBeenCalledTimes(3);
});
it('restarts publishing a beacon after resetting location publish error', async () => {
// always fails to send events
mockClient.sendEvent.mockRejectedValue(new Error('oups'));
@ -1266,21 +1349,5 @@ describe('OwnBeaconStore', () => {
// didn't throw, no error log
expect(loggerErrorSpy).not.toHaveBeenCalled();
});
it('stops live beacons for room after creating new beacon', async () => {
// room1 already has a beacon
makeRoomsWithStateEvents([
alicesRoom1BeaconInfo,
]);
// but it was not created on this device
localStorageGetSpy.mockReturnValue(undefined);
const store = await makeOwnBeaconStore();
const content = makeBeaconInfoContent(100);
await store.createLiveBeacon(room1Id, content);
// update beacon called
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalled();
});
});
});