-
-
Notifications
You must be signed in to change notification settings - Fork 649
Closed
Labels
A-TestingTesting, code coverage, etc.Testing, code coverage, etc.T-TaskTasks for the team like planningTasks for the team like planning
Description
Found while working on #2973 with the jest/valid-expect-in-promise lint
The following test in DeviceList.spec.ts does not wait for the dl.saveIfDirty() async call and assertions
matrix-js-sdk/spec/unit/crypto/DeviceList.spec.ts
Lines 132 to 185 in 193c385
| it("should have an outdated devicelist on an invalidation while an " + "update is in progress", function () { | |
| const dl = createTestDeviceList(); | |
| dl.startTrackingDeviceList("@test1:sw1v.org"); | |
| const queryDefer1 = utils.defer<IDownloadKeyResult>(); | |
| downloadSpy.mockReturnValue(queryDefer1.promise); | |
| const prom1 = dl.refreshOutdatedDeviceLists(); | |
| expect(downloadSpy).toHaveBeenCalledWith(["@test1:sw1v.org"], {}); | |
| downloadSpy.mockReset(); | |
| // outdated notif arrives while the request is in flight. | |
| const queryDefer2 = utils.defer(); | |
| downloadSpy.mockReturnValue(queryDefer2.promise); | |
| dl.invalidateUserDeviceList("@test1:sw1v.org"); | |
| dl.refreshOutdatedDeviceLists(); | |
| dl.saveIfDirty() | |
| .then(() => { | |
| // the first request completes | |
| queryDefer1.resolve({ | |
| failures: {}, | |
| device_keys: { | |
| "@test1:sw1v.org": {}, | |
| }, | |
| }); | |
| return prom1; | |
| }) | |
| .then(() => { | |
| // uh-oh; user restarts before second request completes. The new instance | |
| // should know we never got a complete device list. | |
| logger.log("Creating new devicelist to simulate app reload"); | |
| downloadSpy.mockReset(); | |
| const dl2 = createTestDeviceList(); | |
| const queryDefer3 = utils.defer<IDownloadKeyResult>(); | |
| downloadSpy.mockReturnValue(queryDefer3.promise); | |
| const prom3 = dl2.refreshOutdatedDeviceLists(); | |
| expect(downloadSpy).toHaveBeenCalledWith(["@test1:sw1v.org"], {}); | |
| dl2.stop(); | |
| queryDefer3.resolve(utils.deepCopy(signedDeviceList)); | |
| // allow promise chain to complete | |
| return prom3; | |
| }) | |
| .then(() => { | |
| const storedKeys = dl.getRawStoredDevicesForUser("@test1:sw1v.org"); | |
| expect(Object.keys(storedKeys)).toEqual(["HGKAWHRVJQ"]); | |
| dl.stop(); | |
| }); | |
| }); |
If you try to fix the issue by waiting for the async calls, the test no longer passes which means the test was failing before but we are not catching it.
async/await conversion
it("should have an outdated devicelist on an invalidation while an " + "update is in progress", async () => {
const dl = createTestDeviceList();
dl.startTrackingDeviceList("@test1:sw1v.org");
const queryDefer1 = utils.defer<IDownloadKeyResult>();
downloadSpy.mockReturnValue(queryDefer1.promise);
const prom1 = dl.refreshOutdatedDeviceLists();
expect(downloadSpy).toHaveBeenCalledWith(["@test1:sw1v.org"], {});
downloadSpy.mockReset();
// outdated notif arrives while the request is in flight.
const queryDefer2 = utils.defer();
downloadSpy.mockReturnValue(queryDefer2.promise);
dl.invalidateUserDeviceList("@test1:sw1v.org");
dl.refreshOutdatedDeviceLists();
await dl.saveIfDirty();
// the first request completes
queryDefer1.resolve({
failures: {},
device_keys: {
"@test1:sw1v.org": {},
},
});
await prom1;
// uh-oh; user restarts before second request completes. The new instance
// should know we never got a complete device list.
logger.log("Creating new devicelist to simulate app reload");
downloadSpy.mockReset();
const dl2 = createTestDeviceList();
const queryDefer3 = utils.defer<IDownloadKeyResult>();
downloadSpy.mockReturnValue(queryDefer3.promise);
const prom3 = dl2.refreshOutdatedDeviceLists();
expect(downloadSpy).toHaveBeenCalledWith(["@test1:sw1v.org"], {});
dl2.stop();
queryDefer3.resolve(utils.deepCopy(signedDeviceList));
// allow promise chain to complete
await prom3;
const storedKeys = dl.getRawStoredDevicesForUser("@test1:sw1v.org");
expect(Object.keys(storedKeys)).toEqual(["HGKAWHRVJQ"]);
dl.stop();
});Metadata
Metadata
Assignees
Labels
A-TestingTesting, code coverage, etc.Testing, code coverage, etc.T-TaskTasks for the team like planningTasks for the team like planning