mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2026-02-06 10:46:46 +00:00
fix: address review feedback
- Add PUBLIC_MODE auth guard on bulk-status endpoint - Convert DB models to view models via model_validate() - Early return when no accessible rooms (skip DB queries) - BulkMeetingStatusMap: Partial<Record> for type honesty - Sort roomNames in query key for cache stability - Remove redundant empty-guard in queryFn - Add 7 backend tests: auth, redaction, whereby host_room_url, 401, empty - Add 2 frontend tests: error handling, unauthenticated case
This commit is contained in:
@@ -194,4 +194,53 @@ describe("bulk meeting status (prop-drilling)", () => {
|
||||
// No POST calls when no rooms
|
||||
expect(mockClient.POST).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("surfaces error when POST fails", async () => {
|
||||
mockClient.POST.mockResolvedValue({
|
||||
data: undefined,
|
||||
error: { detail: "server error" },
|
||||
response: {},
|
||||
});
|
||||
|
||||
function ErrorDisplay({ roomNames }: { roomNames: string[] }) {
|
||||
const { error } = useRoomsBulkMeetingStatus(roomNames);
|
||||
if (error) return <div data-testid="error">{error.message}</div>;
|
||||
return <div data-testid="error">no error</div>;
|
||||
}
|
||||
|
||||
render(<ErrorDisplay roomNames={["room-x"]} />, {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("error")).toHaveTextContent(
|
||||
"bulk-status fetch failed",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("does not fetch when unauthenticated", async () => {
|
||||
// Override useAuth to return unauthenticated
|
||||
const authModule = jest.requireMock("../AuthProvider");
|
||||
const originalUseAuth = authModule.useAuth;
|
||||
authModule.useAuth = () => ({
|
||||
...originalUseAuth(),
|
||||
status: "unauthenticated",
|
||||
});
|
||||
|
||||
mockBulkStatusEndpoint();
|
||||
|
||||
render(<BulkStatusDisplay roomNames={["room-1"]} />, {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("status")).toHaveTextContent("no data");
|
||||
});
|
||||
|
||||
expect(mockClient.POST).not.toHaveBeenCalled();
|
||||
|
||||
// Restore
|
||||
authModule.useAuth = originalUseAuth;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -782,15 +782,15 @@ export function useRoomActiveMeetings(roomName: string | null) {
|
||||
|
||||
type RoomMeetingStatus = components["schemas"]["RoomMeetingStatus"];
|
||||
|
||||
export type BulkMeetingStatusMap = Record<string, RoomMeetingStatus>;
|
||||
export type BulkMeetingStatusMap = Partial<Record<string, RoomMeetingStatus>>;
|
||||
|
||||
export function useRoomsBulkMeetingStatus(roomNames: string[]) {
|
||||
const { isAuthenticated } = useAuthReady();
|
||||
const sortedNames = [...roomNames].sort();
|
||||
|
||||
return useQuery({
|
||||
queryKey: ["bulk-meeting-status", roomNames],
|
||||
queryKey: ["bulk-meeting-status", sortedNames],
|
||||
queryFn: async (): Promise<BulkMeetingStatusMap> => {
|
||||
if (roomNames.length === 0) return {};
|
||||
const { data, error } = await client.POST(
|
||||
"/v1/rooms/meetings/bulk-status",
|
||||
{ body: { room_names: roomNames } },
|
||||
@@ -802,7 +802,7 @@ export function useRoomsBulkMeetingStatus(roomNames: string[]) {
|
||||
}
|
||||
return data;
|
||||
},
|
||||
enabled: roomNames.length > 0 && isAuthenticated,
|
||||
enabled: sortedNames.length > 0 && isAuthenticated,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user