Skip to content

Commit b2a1c5c

Browse files
committed
test(matrix): keep async monitor callbacks lint-clean
1 parent 51bad9b commit b2a1c5c

4 files changed

Lines changed: 107 additions & 85 deletions

File tree

extensions/matrix/src/matrix/monitor/auto-join.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ import { setMatrixRuntime } from "../../runtime.js";
44
import type { MatrixConfig } from "../../types.js";
55
import { registerMatrixAutoJoin } from "./auto-join.js";
66

7-
type InviteHandler = (roomId: string, inviteEvent: unknown) => Promise<void>;
7+
type InviteHandler = (roomId: string, inviteEvent: unknown) => void;
8+
9+
async function flushInviteTasks() {
10+
for (let i = 0; i < 5; i += 1) {
11+
await Promise.resolve();
12+
}
13+
}
814

915
function createClientStub() {
1016
let inviteHandler: InviteHandler | null = null;
@@ -62,7 +68,8 @@ async function triggerInvite(
6268
if (!inviteHandler) {
6369
throw new Error("expected Matrix invite handler");
6470
}
65-
await inviteHandler("!room:example.org", inviteEvent);
71+
inviteHandler("!room:example.org", inviteEvent);
72+
await flushInviteTasks();
6673
}
6774

6875
describe("registerMatrixAutoJoin", () => {
@@ -149,7 +156,8 @@ describe("registerMatrixAutoJoin", () => {
149156
if (!inviteHandler) {
150157
throw new Error("expected Matrix invite handler");
151158
}
152-
await expect(inviteHandler("!room:example.org", {})).resolves.toBeUndefined();
159+
inviteHandler("!room:example.org", {});
160+
await flushInviteTasks();
153161

154162
expect(joinRoom).not.toHaveBeenCalled();
155163
expect(error).toHaveBeenCalledWith(

extensions/matrix/src/matrix/monitor/auto-join.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ export function registerMatrixAutoJoin(params: {
6060
};
6161

6262
// Handle invites directly so both "always" and "allowlist" modes share the same path.
63-
client.on("room.invite", (roomId: string, _inviteEvent: unknown) =>
64-
(async () => {
63+
client.on("room.invite", (roomId: string, _inviteEvent: unknown) => {
64+
void (async () => {
6565
if (autoJoin === "allowlist") {
6666
const allowedAliasRoomIds = await resolveAllowedAliasRoomIds();
6767
const allowed =
@@ -81,6 +81,6 @@ export function registerMatrixAutoJoin(params: {
8181
} catch (err) {
8282
runtime.error?.(`matrix: failed to join room ${roomId}: ${String(err)}`);
8383
}
84-
})(),
85-
);
84+
})();
85+
});
8686
}

extensions/matrix/src/matrix/monitor/events.test.ts

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { MatrixRawEvent } from "./types.js";
88
import { EventType } from "./types.js";
99

1010
type RoomEventListener = (roomId: string, event: MatrixRawEvent) => void;
11-
type FailedDecryptListener = (roomId: string, event: MatrixRawEvent, error: Error) => Promise<void>;
11+
type FailedDecryptListener = (roomId: string, event: MatrixRawEvent, error: Error) => void;
1212
type VerificationSummaryListener = (summary: MatrixVerificationSummary) => void;
1313

1414
function getSentNoticeBody(sendMessage: ReturnType<typeof vi.fn>, index = 0): string {
@@ -1489,15 +1489,15 @@ describe("registerMatrixMonitorEvents verification routing", () => {
14891489
});
14901490

14911491
it("adds self-device guidance when decrypt failures come from the same Matrix user", async () => {
1492-
const { logger, failedDecryptListener } = createHarness({
1492+
const { logger, failedDecryptListener, flushTasks } = createHarness({
14931493
accountId: "ops",
14941494
selfUserId: "@gumadeiras:matrix.example.org",
14951495
});
14961496
if (!failedDecryptListener) {
14971497
throw new Error("room.failed_decryption listener was not registered");
14981498
}
14991499

1500-
await failedDecryptListener(
1500+
failedDecryptListener(
15011501
"!room:example.org",
15021502
{
15031503
event_id: "$enc-self",
@@ -1508,6 +1508,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
15081508
},
15091509
new Error("The sender's device has not sent us the keys for this message."),
15101510
);
1511+
await flushTasks();
15111512

15121513
expectWarnContextFields(logger, 1, "Failed to decrypt message", {
15131514
roomId: "!room:example.org",
@@ -1527,15 +1528,15 @@ describe("registerMatrixMonitorEvents verification routing", () => {
15271528
});
15281529

15291530
it("does not add self-device guidance for decrypt failures from another sender", async () => {
1530-
const { logger, failedDecryptListener } = createHarness({
1531+
const { logger, failedDecryptListener, flushTasks } = createHarness({
15311532
accountId: "ops",
15321533
selfUserId: "@gumadeiras:matrix.example.org",
15331534
});
15341535
if (!failedDecryptListener) {
15351536
throw new Error("room.failed_decryption listener was not registered");
15361537
}
15371538

1538-
await failedDecryptListener(
1539+
failedDecryptListener(
15391540
"!room:example.org",
15401541
{
15411542
event_id: "$enc-other",
@@ -1546,6 +1547,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
15461547
},
15471548
new Error("The sender's device has not sent us the keys for this message."),
15481549
);
1550+
await flushTasks();
15491551

15501552
expect(logger.warn).toHaveBeenCalledTimes(1);
15511553
expectWarnContextFields(logger, 1, "Failed to decrypt message", {
@@ -1561,7 +1563,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
15611563
vi.setSystemTime(new Date("2026-04-10T16:21:00.000Z"));
15621564
try {
15631565
const healthySyncSinceMs = Date.now() - 60_000;
1564-
const { logger, failedDecryptListener } = createHarness({
1566+
const { logger, failedDecryptListener, flushTasks } = createHarness({
15651567
accountId: "ops",
15661568
getHealthySyncSinceMs: () => healthySyncSinceMs,
15671569
});
@@ -1574,7 +1576,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
15741576
"!room-b:example.org",
15751577
"!room-c:example.org",
15761578
].entries()) {
1577-
await failedDecryptListener(
1579+
failedDecryptListener(
15781580
roomId,
15791581
{
15801582
event_id: `$enc-fresh-${index + 1}`,
@@ -1585,6 +1587,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
15851587
},
15861588
new Error("The sender's device has not sent us the keys for this message."),
15871589
);
1590+
await flushTasks();
15881591
}
15891592

15901593
expectWarnContextFields(logger, 1, "Failed to decrypt fresh post-healthy-sync message", {
@@ -1624,15 +1627,15 @@ describe("registerMatrixMonitorEvents verification routing", () => {
16241627
vi.setSystemTime(new Date("2026-04-10T16:21:00.000Z"));
16251628
try {
16261629
const healthySync = { sinceMs: undefined as number | undefined };
1627-
const { logger, failedDecryptListener } = createHarness({
1630+
const { logger, failedDecryptListener, flushTasks } = createHarness({
16281631
accountId: "ops",
16291632
getHealthySyncSinceMs: () => healthySync.sinceMs,
16301633
});
16311634
if (!failedDecryptListener) {
16321635
throw new Error("room.failed_decryption listener was not registered");
16331636
}
16341637

1635-
await failedDecryptListener(
1638+
failedDecryptListener(
16361639
"!room:example.org",
16371640
{
16381641
event_id: "$enc-old",
@@ -1643,6 +1646,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
16431646
},
16441647
new Error("The sender's device has not sent us the keys for this message."),
16451648
);
1649+
await flushTasks();
16461650

16471651
expect(logger.warn).toHaveBeenCalledTimes(1);
16481652
expectWarnContextFields(logger, 1, "Failed to decrypt message", {
@@ -1652,7 +1656,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
16521656

16531657
healthySync.sinceMs = Date.now();
16541658

1655-
await failedDecryptListener(
1659+
failedDecryptListener(
16561660
"!room:example.org",
16571661
{
16581662
event_id: "$enc-fresh-after-ready",
@@ -1663,6 +1667,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
16631667
},
16641668
new Error("The sender's device has not sent us the keys for this message."),
16651669
);
1670+
await flushTasks();
16661671

16671672
expectWarnContextFields(logger, 2, "Failed to decrypt fresh post-healthy-sync message", {
16681673
eventId: "$enc-fresh-after-ready",
@@ -1679,7 +1684,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
16791684
vi.setSystemTime(new Date("2026-04-10T16:21:00.000Z"));
16801685
try {
16811686
const healthySyncSinceMs = Date.now() - 60_000;
1682-
const { logger, failedDecryptListener } = createHarness({
1687+
const { logger, failedDecryptListener, flushTasks } = createHarness({
16831688
accountId: "ops",
16841689
getHealthySyncSinceMs: () => healthySyncSinceMs,
16851690
});
@@ -1689,7 +1694,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
16891694

16901695
for (const wave of [1, 2]) {
16911696
for (const index of [1, 2, 3]) {
1692-
await failedDecryptListener(
1697+
failedDecryptListener(
16931698
`!room-${wave}-${index}:example.org`,
16941699
{
16951700
event_id: `$enc-wave-${wave}-${index}`,
@@ -1700,6 +1705,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
17001705
},
17011706
new Error("The sender's device has not sent us the keys for this message."),
17021707
);
1708+
await flushTasks();
17031709
}
17041710

17051711
if (wave === 1) {
@@ -1733,7 +1739,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
17331739
vi.setSystemTime(new Date("2026-04-10T16:21:00.000Z"));
17341740
try {
17351741
let healthySyncSinceMs = Date.now() - 60_000;
1736-
const { logger, failedDecryptListener } = createHarness({
1742+
const { logger, failedDecryptListener, flushTasks } = createHarness({
17371743
accountId: "ops",
17381744
getHealthySyncSinceMs: () => healthySyncSinceMs,
17391745
});
@@ -1742,7 +1748,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
17421748
}
17431749

17441750
for (const index of [1, 2, 3]) {
1745-
await failedDecryptListener(
1751+
failedDecryptListener(
17461752
`!room-first-${index}:example.org`,
17471753
{
17481754
event_id: `$enc-first-${index}`,
@@ -1753,12 +1759,13 @@ describe("registerMatrixMonitorEvents verification routing", () => {
17531759
},
17541760
new Error("The sender's device has not sent us the keys for this message."),
17551761
);
1762+
await flushTasks();
17561763
}
17571764

17581765
healthySyncSinceMs = Date.now();
17591766

17601767
for (const index of [1, 2, 3]) {
1761-
await failedDecryptListener(
1768+
failedDecryptListener(
17621769
`!room-second-${index}:example.org`,
17631770
{
17641771
event_id: `$enc-second-${index}`,
@@ -1769,6 +1776,7 @@ describe("registerMatrixMonitorEvents verification routing", () => {
17691776
},
17701777
new Error("The sender's device has not sent us the keys for this message."),
17711778
);
1779+
await flushTasks();
17721780
}
17731781

17741782
expectWarnContextFields(logger, 5, "Failed to decrypt fresh post-healthy-sync message", {
@@ -1800,27 +1808,26 @@ describe("registerMatrixMonitorEvents verification routing", () => {
18001808
});
18011809

18021810
it("logs decrypt guidance when getUserId fails during lookup", async () => {
1803-
const { logger, logVerboseMessage, failedDecryptListener } = createHarness({
1811+
const { logger, logVerboseMessage, failedDecryptListener, flushTasks } = createHarness({
18041812
accountId: "ops",
18051813
selfUserIdError: new Error("lookup failed"),
18061814
});
18071815
if (!failedDecryptListener) {
18081816
throw new Error("room.failed_decryption listener was not registered");
18091817
}
18101818

1811-
await expect(
1812-
failedDecryptListener(
1813-
"!room:example.org",
1814-
{
1815-
event_id: "$enc-lookup-fail",
1816-
sender: "@gumadeiras:matrix.example.org",
1817-
type: EventType.RoomMessageEncrypted,
1818-
origin_server_ts: Date.now(),
1819-
content: {},
1820-
},
1821-
new Error("The sender's device has not sent us the keys for this message."),
1822-
),
1823-
).resolves.toBeUndefined();
1819+
failedDecryptListener(
1820+
"!room:example.org",
1821+
{
1822+
event_id: "$enc-lookup-fail",
1823+
sender: "@gumadeiras:matrix.example.org",
1824+
type: EventType.RoomMessageEncrypted,
1825+
origin_server_ts: Date.now(),
1826+
content: {},
1827+
},
1828+
new Error("The sender's device has not sent us the keys for this message."),
1829+
);
1830+
await flushTasks();
18241831

18251832
expect(logger.warn).toHaveBeenCalledTimes(1);
18261833
expectWarnContextFields(logger, 1, "Failed to decrypt message", {

0 commit comments

Comments
 (0)