From 8f3c7149f6c7439398a022cf96b14dbd7d879372 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Sun, 10 Apr 2022 02:22:04 +0100 Subject: [PATCH 1/4] Fix MatrixClientPeg.userRegisteredWithinLastHours so that it works --- src/MatrixClientPeg.ts | 19 ++++++---- test/MatrixClientPeg-test.ts | 69 ++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 test/MatrixClientPeg-test.ts diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index 7949518fc2e..417a0b833b8 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -117,7 +117,9 @@ class MatrixClientPegClass implements IMatrixClientPeg { }; private matrixClient: MatrixClient = null; - private justRegisteredUserId: string; + private justRegisteredUserId: string | null = null; + private registrationTime?: number; + private registrationTimeUser?: string; // the credentials used to init the current client object. // used if we tear it down & recreate it with a different store @@ -136,10 +138,11 @@ class MatrixClientPegClass implements IMatrixClientPeg { MatrixActionCreators.stop(); } - public setJustRegisteredUserId(uid: string): void { + public setJustRegisteredUserId(uid: string | null): void { this.justRegisteredUserId = uid; if (uid) { - window.localStorage.setItem("mx_registration_time", String(new Date().getTime())); + this.registrationTime = Date.now(); + this.registrationTimeUser = uid; } } @@ -151,12 +154,14 @@ class MatrixClientPegClass implements IMatrixClientPeg { } public userRegisteredWithinLastHours(hours: number): boolean { - try { - const date = new Date(window.localStorage.getItem("mx_registration_time")); - return ((new Date().getTime() - date.getTime()) / 36e5) <= hours; - } catch (e) { + if ( + !this.registrationTime || + hours <= 0 || + this.registrationTimeUser !== this.matrixClient?.credentials.userId + ) { return false; } + return ((Date.now() - this.registrationTime) / 36e5) <= hours; } public replaceUsingCreds(creds: IMatrixClientCreds): void { diff --git a/test/MatrixClientPeg-test.ts b/test/MatrixClientPeg-test.ts new file mode 100644 index 00000000000..1d0d9574f39 --- /dev/null +++ b/test/MatrixClientPeg-test.ts @@ -0,0 +1,69 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +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 { stubClient } from "./test-utils"; +import { MatrixClientPeg as peg } from "../src/MatrixClientPeg"; + +describe("MatrixClientPeg", () => { + afterEach(() => { + (peg as any).registrationTime = undefined; + (peg as any).registrationTimeUser = undefined; + }); + + it("setJustRegisteredUserId", () => { + stubClient(); + (peg as any).matrixClient = peg.get(); + peg.setJustRegisteredUserId("@userId:matrix.rog"); + expect(peg.get().credentials.userId).toBe("@userId:matrix.rog"); + expect(peg.currentUserIsJustRegistered()).toBe(true); + expect(peg.userRegisteredWithinLastHours(0)).toBe(false); + expect(peg.userRegisteredWithinLastHours(1)).toBe(true); + expect(peg.userRegisteredWithinLastHours(24)).toBe(true); + }); + + it("setJustRegisteredUserId(null)", () => { + stubClient(); + (peg as any).matrixClient = peg.get(); + peg.setJustRegisteredUserId(null); + expect(peg.currentUserIsJustRegistered()).toBe(false); + expect(peg.userRegisteredWithinLastHours(0)).toBe(false); + expect(peg.userRegisteredWithinLastHours(1)).toBe(false); + expect(peg.userRegisteredWithinLastHours(24)).toBe(false); + }); + + it("multiple users", () => { + stubClient(); + (peg as any).matrixClient = peg.get(); + peg.setJustRegisteredUserId("@userId:matrix.rog"); + expect(peg.get().credentials.userId).toBe("@userId:matrix.rog"); + expect(peg.currentUserIsJustRegistered()).toBe(true); + expect(peg.userRegisteredWithinLastHours(0)).toBe(false); + expect(peg.userRegisteredWithinLastHours(1)).toBe(true); + expect(peg.userRegisteredWithinLastHours(24)).toBe(true); + + peg.setJustRegisteredUserId("@userId2:matrix.rog"); + expect(peg.currentUserIsJustRegistered()).toBe(false); + expect(peg.userRegisteredWithinLastHours(0)).toBe(false); + expect(peg.userRegisteredWithinLastHours(1)).toBe(false); + expect(peg.userRegisteredWithinLastHours(24)).toBe(false); + + peg.get().credentials.userId = "@userId2:matrix.rog"; + expect(peg.currentUserIsJustRegistered()).toBe(true); + expect(peg.userRegisteredWithinLastHours(0)).toBe(false); + expect(peg.userRegisteredWithinLastHours(1)).toBe(true); + expect(peg.userRegisteredWithinLastHours(24)).toBe(true); + }); +}); From 7750d8b9db709127c3eb7a120a8cc31089583c4a Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Sun, 10 Apr 2022 02:51:59 +0100 Subject: [PATCH 2/4] Try fixing end-to-end test + add case for New search beta --- test/end-to-end-tests/src/scenarios/toast.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test/end-to-end-tests/src/scenarios/toast.ts b/test/end-to-end-tests/src/scenarios/toast.ts index c8f094f840b..de0804d8058 100644 --- a/test/end-to-end-tests/src/scenarios/toast.ts +++ b/test/end-to-end-tests/src/scenarios/toast.ts @@ -14,6 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { sleep } from "matrix-js-sdk/src/utils"; + import { assertNoToasts, acceptToast, rejectToast } from "../usecases/toasts"; import { ElementSession } from "../session"; @@ -21,10 +23,6 @@ export async function toastScenarios(alice: ElementSession, bob: ElementSession) console.log(" checking and clearing toasts:"); alice.log.startGroup(`clears toasts`); - alice.log.step(`reject desktop notifications toast`); - await rejectToast(alice, "Notifications"); - alice.log.done(); - alice.log.step(`accepts analytics toast`); await acceptToast(alice, "Help improve Element"); alice.log.done(); @@ -35,10 +33,6 @@ export async function toastScenarios(alice: ElementSession, bob: ElementSession) alice.log.endGroup(); bob.log.startGroup(`clears toasts`); - bob.log.step(`reject desktop notifications toast`); - await rejectToast(bob, "Notifications"); - bob.log.done(); - bob.log.step(`reject analytics toast`); await rejectToast(bob, "Help improve Element"); bob.log.done(); @@ -46,5 +40,15 @@ export async function toastScenarios(alice: ElementSession, bob: ElementSession) bob.log.step(`checks no remaining toasts`); await assertNoToasts(bob); bob.log.done(); + + await sleep(60); // wait for the search beta toast to show + + bob.log.step(`accept search beta toast`); + await acceptToast(bob, "New search beta available"); + bob.log.done(); + + alice.log.step(`checks no remaining toasts`); + await assertNoToasts(alice); + alice.log.done(); bob.log.endGroup(); } From 7ff428073422b5c54c29a2cac5c0f9563924de55 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Sun, 10 Apr 2022 02:55:14 +0100 Subject: [PATCH 3/4] Remove end-to-end test case for Search beta toast as it only shows up after 5 minutes --- test/end-to-end-tests/src/scenarios/toast.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/end-to-end-tests/src/scenarios/toast.ts b/test/end-to-end-tests/src/scenarios/toast.ts index de0804d8058..bf7dbe809b6 100644 --- a/test/end-to-end-tests/src/scenarios/toast.ts +++ b/test/end-to-end-tests/src/scenarios/toast.ts @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { sleep } from "matrix-js-sdk/src/utils"; - import { assertNoToasts, acceptToast, rejectToast } from "../usecases/toasts"; import { ElementSession } from "../session"; @@ -40,15 +38,5 @@ export async function toastScenarios(alice: ElementSession, bob: ElementSession) bob.log.step(`checks no remaining toasts`); await assertNoToasts(bob); bob.log.done(); - - await sleep(60); // wait for the search beta toast to show - - bob.log.step(`accept search beta toast`); - await acceptToast(bob, "New search beta available"); - bob.log.done(); - - alice.log.step(`checks no remaining toasts`); - await assertNoToasts(alice); - alice.log.done(); bob.log.endGroup(); } From 4f9d176105557f7fa8503ffdef89b9915a6865f3 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 13 Apr 2022 16:45:08 +0100 Subject: [PATCH 4/4] Revert to localStorage based solution + non-inverted logic + test including time advancement --- src/Lifecycle.ts | 9 +++++++-- src/MatrixClientPeg.ts | 20 ++++++++++---------- test/MatrixClientPeg-test.ts | 35 ++++++++++++----------------------- 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/Lifecycle.ts b/src/Lifecycle.ts index 90ead50fa6a..da4010c57ea 100644 --- a/src/Lifecycle.ts +++ b/src/Lifecycle.ts @@ -875,8 +875,9 @@ async function clearStorage(opts?: { deleteEverything?: boolean }): Promise { const roomId = i.roomId; delete i.roomId; // delete to avoid confusing the store ThreepidInviteStore.instance.storeInvite(roomId, i); }); + + if (registrationTime) { + window.localStorage.setItem("mx_registration_time", registrationTime); + } } } diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index 417a0b833b8..0ef270051c9 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -118,8 +118,6 @@ class MatrixClientPegClass implements IMatrixClientPeg { private matrixClient: MatrixClient = null; private justRegisteredUserId: string | null = null; - private registrationTime?: number; - private registrationTimeUser?: string; // the credentials used to init the current client object. // used if we tear it down & recreate it with a different store @@ -141,8 +139,7 @@ class MatrixClientPegClass implements IMatrixClientPeg { public setJustRegisteredUserId(uid: string | null): void { this.justRegisteredUserId = uid; if (uid) { - this.registrationTime = Date.now(); - this.registrationTimeUser = uid; + window.localStorage.setItem("mx_registration_time", String(new Date().getTime())); } } @@ -154,14 +151,17 @@ class MatrixClientPegClass implements IMatrixClientPeg { } public userRegisteredWithinLastHours(hours: number): boolean { - if ( - !this.registrationTime || - hours <= 0 || - this.registrationTimeUser !== this.matrixClient?.credentials.userId - ) { + if (hours <= 0) { + return false; + } + + try { + const registrationTime = parseInt(window.localStorage.getItem("mx_registration_time")); + const diff = Date.now() - registrationTime; + return (diff / 36e5) <= hours; + } catch (e) { return false; } - return ((Date.now() - this.registrationTime) / 36e5) <= hours; } public replaceUsingCreds(creds: IMatrixClientCreds): void { diff --git a/test/MatrixClientPeg-test.ts b/test/MatrixClientPeg-test.ts index 1d0d9574f39..f3f6826c15c 100644 --- a/test/MatrixClientPeg-test.ts +++ b/test/MatrixClientPeg-test.ts @@ -14,13 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { stubClient } from "./test-utils"; +import { advanceDateAndTime, stubClient } from "./test-utils"; import { MatrixClientPeg as peg } from "../src/MatrixClientPeg"; describe("MatrixClientPeg", () => { afterEach(() => { - (peg as any).registrationTime = undefined; - (peg as any).registrationTimeUser = undefined; + localStorage.clear(); + advanceDateAndTime(0); }); it("setJustRegisteredUserId", () => { @@ -32,6 +32,14 @@ describe("MatrixClientPeg", () => { expect(peg.userRegisteredWithinLastHours(0)).toBe(false); expect(peg.userRegisteredWithinLastHours(1)).toBe(true); expect(peg.userRegisteredWithinLastHours(24)).toBe(true); + advanceDateAndTime(1 * 60 * 60 * 1000); + expect(peg.userRegisteredWithinLastHours(0)).toBe(false); + expect(peg.userRegisteredWithinLastHours(1)).toBe(false); + expect(peg.userRegisteredWithinLastHours(24)).toBe(true); + advanceDateAndTime(24 * 60 * 60 * 1000); + expect(peg.userRegisteredWithinLastHours(0)).toBe(false); + expect(peg.userRegisteredWithinLastHours(1)).toBe(false); + expect(peg.userRegisteredWithinLastHours(24)).toBe(false); }); it("setJustRegisteredUserId(null)", () => { @@ -42,28 +50,9 @@ describe("MatrixClientPeg", () => { expect(peg.userRegisteredWithinLastHours(0)).toBe(false); expect(peg.userRegisteredWithinLastHours(1)).toBe(false); expect(peg.userRegisteredWithinLastHours(24)).toBe(false); - }); - - it("multiple users", () => { - stubClient(); - (peg as any).matrixClient = peg.get(); - peg.setJustRegisteredUserId("@userId:matrix.rog"); - expect(peg.get().credentials.userId).toBe("@userId:matrix.rog"); - expect(peg.currentUserIsJustRegistered()).toBe(true); - expect(peg.userRegisteredWithinLastHours(0)).toBe(false); - expect(peg.userRegisteredWithinLastHours(1)).toBe(true); - expect(peg.userRegisteredWithinLastHours(24)).toBe(true); - - peg.setJustRegisteredUserId("@userId2:matrix.rog"); - expect(peg.currentUserIsJustRegistered()).toBe(false); + advanceDateAndTime(1 * 60 * 60 * 1000); expect(peg.userRegisteredWithinLastHours(0)).toBe(false); expect(peg.userRegisteredWithinLastHours(1)).toBe(false); expect(peg.userRegisteredWithinLastHours(24)).toBe(false); - - peg.get().credentials.userId = "@userId2:matrix.rog"; - expect(peg.currentUserIsJustRegistered()).toBe(true); - expect(peg.userRegisteredWithinLastHours(0)).toBe(false); - expect(peg.userRegisteredWithinLastHours(1)).toBe(true); - expect(peg.userRegisteredWithinLastHours(24)).toBe(true); }); });