1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-05 00:42:10 +03:00

Make DeviceList test pass

Includes making saveIfDirty() return a promise in case you care
about when changes got saved (which the test does).
This commit is contained in:
David Baker
2018-01-15 15:21:39 +00:00
parent 36d7d33afc
commit 110f43a246
2 changed files with 26 additions and 13 deletions

View File

@@ -1,6 +1,7 @@
import DeviceList from '../../../lib/crypto/DeviceList'; import DeviceList from '../../../lib/crypto/DeviceList';
import MockStorageApi from '../../MockStorageApi'; import MockStorageApi from '../../MockStorageApi';
import WebStorageSessionStore from '../../../lib/store/session/webstorage'; import WebStorageSessionStore from '../../../lib/store/session/webstorage';
import MemoryCryptoStore from '../../../lib/crypto/store/memory-crypto-store.js';
import testUtils from '../../test-utils'; import testUtils from '../../test-utils';
import utils from '../../../lib/utils'; import utils from '../../../lib/utils';
@@ -40,6 +41,7 @@ const signedDeviceList = {
describe('DeviceList', function() { describe('DeviceList', function() {
let downloadSpy; let downloadSpy;
let sessionStore; let sessionStore;
let cryptoStore;
beforeEach(function() { beforeEach(function() {
testUtils.beforeEach(this); // eslint-disable-line no-invalid-this testUtils.beforeEach(this); // eslint-disable-line no-invalid-this
@@ -47,6 +49,7 @@ describe('DeviceList', function() {
downloadSpy = expect.createSpy(); downloadSpy = expect.createSpy();
const mockStorage = new MockStorageApi(); const mockStorage = new MockStorageApi();
sessionStore = new WebStorageSessionStore(mockStorage); sessionStore = new WebStorageSessionStore(mockStorage);
cryptoStore = new MemoryCryptoStore(mockStorage);
}); });
function createTestDeviceList() { function createTestDeviceList() {
@@ -56,7 +59,7 @@ describe('DeviceList', function() {
const mockOlm = { const mockOlm = {
verifySignature: function(key, message, signature) {}, verifySignature: function(key, message, signature) {},
}; };
return new DeviceList(baseApis, sessionStore, mockOlm); return new DeviceList(baseApis, cryptoStore, sessionStore, mockOlm);
} }
it("should successfully download and store device keys", function() { it("should successfully download and store device keys", function() {
@@ -72,7 +75,7 @@ describe('DeviceList', function() {
queryDefer1.resolve(utils.deepCopy(signedDeviceList)); queryDefer1.resolve(utils.deepCopy(signedDeviceList));
return prom1.then(() => { return prom1.then(() => {
const storedKeys = sessionStore.getEndToEndDevicesForUser('@test1:sw1v.org'); const storedKeys = dl.getRawStoredDevicesForUser('@test1:sw1v.org');
expect(Object.keys(storedKeys)).toEqual(['HGKAWHRVJQ']); expect(Object.keys(storedKeys)).toEqual(['HGKAWHRVJQ']);
}); });
}); });
@@ -97,14 +100,15 @@ describe('DeviceList', function() {
dl.invalidateUserDeviceList('@test1:sw1v.org'); dl.invalidateUserDeviceList('@test1:sw1v.org');
dl.refreshOutdatedDeviceLists(); dl.refreshOutdatedDeviceLists();
// the first request completes dl.saveIfDirty().then(() => {
queryDefer1.resolve({ // the first request completes
device_keys: { queryDefer1.resolve({
'@test1:sw1v.org': {}, device_keys: {
}, '@test1:sw1v.org': {},
}); },
});
return prom1.then(() => { return prom1;
}).then(() => {
// uh-oh; user restarts before second request completes. The new instance // uh-oh; user restarts before second request completes. The new instance
// should know we never got a complete device list. // should know we never got a complete device list.
console.log("Creating new devicelist to simulate app reload"); console.log("Creating new devicelist to simulate app reload");
@@ -121,7 +125,7 @@ describe('DeviceList', function() {
// allow promise chain to complete // allow promise chain to complete
return prom3; return prom3;
}).then(() => { }).then(() => {
const storedKeys = sessionStore.getEndToEndDevicesForUser('@test1:sw1v.org'); const storedKeys = dl.getRawStoredDevicesForUser('@test1:sw1v.org');
expect(Object.keys(storedKeys)).toEqual(['HGKAWHRVJQ']); expect(Object.keys(storedKeys)).toEqual(['HGKAWHRVJQ']);
}); });
}); });

View File

@@ -91,6 +91,8 @@ export default class DeviceList {
// Timeout for a scheduled save // Timeout for a scheduled save
this._saveTimer = null; this._saveTimer = null;
// Promise resolved when device data is saved
this._savePromise = null;
} }
/** /**
@@ -141,14 +143,18 @@ export default class DeviceList {
/** /**
* Save the device tracking state to storage, if any changes are * Save the device tracking state to storage, if any changes are
* pending other than updating the sync token * pending other than updating the sync token
*
* @return {Promise<bool>} True is the data was saved, false if
* it was not (eg. because no changes were pending)
*/ */
async saveIfDirty() { async saveIfDirty() {
if (!this._dirty) return; if (!this._dirty) return Promise.resolve(False);
if (this._saveTimer === null) { if (this._saveTimer === null) {
this._saveTimer = setTimeout(() => { this._saveTimer = setTimeout(() => {
console.log('Saving device tracking data...');
this._saveTimer = null; this._saveTimer = null;
this._cryptoStore.doTxn( this._savePromise = this._cryptoStore.doTxn(
'readwrite', [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => { 'readwrite', [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => {
this._cryptoStore.storeEndToEndDeviceData({ this._cryptoStore.storeEndToEndDeviceData({
devices: this._devices, devices: this._devices,
@@ -158,8 +164,11 @@ export default class DeviceList {
}, },
).then(() => { ).then(() => {
this._dirty = false; this._dirty = false;
return True;
}); });
}, 500); }, 500);
} else {
return this._savePromise;
} }
} }