feat(bd-2vw): display raw lore data in debug view
Add DebugView component to show raw lore status data for visual verification that the data pipeline works end-to-end: - Frontend -> Tauri IPC -> Rust backend -> lore CLI -> parsed data New files: - src/components/DebugView.tsx - Debug component with health indicator - src/hooks/useLoreData.ts - TanStack Query hook for lore status - tests/components/DebugView.test.tsx - Component tests - tests/hooks/useLoreData.test.ts - Hook tests Modified: - src/App.tsx - Add QueryClientProvider wrapper - src/stores/nav-store.ts - Add 'debug' ViewId - src/components/AppShell.tsx - Add Debug nav tab and view routing - tests/components/AppShell.test.tsx - Update tests for new nav
This commit is contained in:
97
tests/hooks/useLoreData.test.ts
Normal file
97
tests/hooks/useLoreData.test.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||
import { renderHook, waitFor } from "@testing-library/react";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { createElement } from "react";
|
||||
import { useLoreData } from "@/hooks/useLoreData";
|
||||
import { setMockResponse, resetMocks } from "../mocks/tauri-api";
|
||||
|
||||
function createWrapper() {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
return function Wrapper({ children }: { children: React.ReactNode }) {
|
||||
return createElement(QueryClientProvider, { client: queryClient }, children);
|
||||
};
|
||||
}
|
||||
|
||||
describe("useLoreData", () => {
|
||||
beforeEach(() => {
|
||||
resetMocks();
|
||||
});
|
||||
|
||||
it("returns loading state initially", () => {
|
||||
const { result } = renderHook(() => useLoreData(), {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
|
||||
expect(result.current.isLoading).toBe(true);
|
||||
expect(result.current.data).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns lore status data on success", async () => {
|
||||
const mockStatus = {
|
||||
last_sync: "2026-02-26T12:00:00Z",
|
||||
is_healthy: true,
|
||||
message: "Lore is healthy",
|
||||
summary: {
|
||||
open_issues: 5,
|
||||
authored_mrs: 2,
|
||||
reviewing_mrs: 3,
|
||||
},
|
||||
};
|
||||
|
||||
setMockResponse("get_lore_status", mockStatus);
|
||||
|
||||
const { result } = renderHook(() => useLoreData(), {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.isLoading).toBe(false);
|
||||
});
|
||||
|
||||
expect(result.current.data).toEqual(mockStatus);
|
||||
expect(result.current.error).toBeNull();
|
||||
});
|
||||
|
||||
it("returns error state when IPC fails", async () => {
|
||||
setMockResponse("get_lore_status", Promise.reject(new Error("IPC failed")));
|
||||
|
||||
const { result } = renderHook(() => useLoreData(), {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.isLoading).toBe(false);
|
||||
});
|
||||
|
||||
expect(result.current.error).toBeTruthy();
|
||||
expect(result.current.data).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns unhealthy status", async () => {
|
||||
const mockStatus = {
|
||||
last_sync: null,
|
||||
is_healthy: false,
|
||||
message: "lore not configured",
|
||||
summary: null,
|
||||
};
|
||||
|
||||
setMockResponse("get_lore_status", mockStatus);
|
||||
|
||||
const { result } = renderHook(() => useLoreData(), {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.isLoading).toBe(false);
|
||||
});
|
||||
|
||||
expect(result.current.data?.is_healthy).toBe(false);
|
||||
expect(result.current.data?.summary).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user