diff --git a/src/app/hooks/useRoomMembers.test.tsx b/src/app/hooks/useRoomMembers.test.tsx new file mode 100644 index 000000000..162126c2e --- /dev/null +++ b/src/app/hooks/useRoomMembers.test.tsx @@ -0,0 +1,35 @@ +import { renderHook, waitFor } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; +import type { MatrixClient, Room, RoomMember } from '$types/matrix-sdk'; + +const { hydrateAllRoomMembers } = vi.hoisted(() => ({ + hydrateAllRoomMembers: vi.fn<() => Promise>().mockResolvedValue(undefined), +})); + +vi.mock('$client/roomMemberHydration', () => ({ hydrateAllRoomMembers })); + +import { useRoomMembers } from './useRoomMembers'; + +describe('useRoomMembers', () => { + it('does not retry with a full roster request when the SDK member load fails', async () => { + const room = { + roomId: '!room:example.org', + getMembers: () => [] as RoomMember[], + loadMembersIfNeeded: vi + .fn<() => Promise>() + .mockRejectedValue(new Error('NetworkError')), + } as unknown as Room; + const mx = { + getRoom: () => room, + on: vi.fn<() => void>(), + removeListener: vi.fn<() => void>(), + } as unknown as MatrixClient; + + renderHook(() => useRoomMembers(mx, room.roomId)); + + await waitFor(() => expect(room.loadMembersIfNeeded).toHaveBeenCalledOnce()); + await Promise.resolve(); + + expect(hydrateAllRoomMembers).not.toHaveBeenCalled(); + }); +}); diff --git a/src/app/hooks/useRoomMembers.ts b/src/app/hooks/useRoomMembers.ts index 4469680d6..f953e3ea2 100644 --- a/src/app/hooks/useRoomMembers.ts +++ b/src/app/hooks/useRoomMembers.ts @@ -28,9 +28,11 @@ export const useRoomMembers = (mx: MatrixClient, roomId: string, enabled = true) loadingMembers = false; if (disposed) return; updateMemberList(); - void hydrateAllRoomMembers(mx, roomId).then(() => updateMemberList()); }; - room.loadMembersIfNeeded().then(stopLoading, stopLoading); + room.loadMembersIfNeeded().then(() => { + stopLoading(); + void hydrateAllRoomMembers(mx, roomId).then(() => updateMemberList()); + }, stopLoading); } const handleStateEvent = (event: MatrixEvent) => {