From 84ae5b4ca991efa2893535d5aa0da90774c97ab8 Mon Sep 17 00:00:00 2001
From: SagarRajput-7 <162284829+SagarRajput-7@users.noreply.github.com>
Date: Mon, 22 Sep 2025 11:53:14 +0530
Subject: [PATCH] fix: added dashboard route param, to allow trigger when new
panel creation action happens (#9141)
---
.../src/providers/Dashboard/Dashboard.tsx | 2 +-
.../Dashboard/__tests__/Dashboard.test.tsx | 292 ++++++++++++++++++
2 files changed, 293 insertions(+), 1 deletion(-)
create mode 100644 frontend/src/providers/Dashboard/__tests__/Dashboard.test.tsx
diff --git a/frontend/src/providers/Dashboard/Dashboard.tsx b/frontend/src/providers/Dashboard/Dashboard.tsx
index 395858b77b8f..c8aa3c7d51b0 100644
--- a/frontend/src/providers/Dashboard/Dashboard.tsx
+++ b/frontend/src/providers/Dashboard/Dashboard.tsx
@@ -269,7 +269,7 @@ export function DashboardProvider({
return data;
};
const dashboardResponse = useQuery(
- [REACT_QUERY_KEY.DASHBOARD_BY_ID, dashboardId],
+ [REACT_QUERY_KEY.DASHBOARD_BY_ID, isDashboardPage?.params, dashboardId],
{
enabled: (!!isDashboardPage || !!isDashboardWidgetPage) && isLoggedIn,
queryFn: async () => {
diff --git a/frontend/src/providers/Dashboard/__tests__/Dashboard.test.tsx b/frontend/src/providers/Dashboard/__tests__/Dashboard.test.tsx
new file mode 100644
index 000000000000..feb7905cbb2c
--- /dev/null
+++ b/frontend/src/providers/Dashboard/__tests__/Dashboard.test.tsx
@@ -0,0 +1,292 @@
+/* eslint-disable sonarjs/no-duplicate-string */
+import { render, waitFor } from '@testing-library/react';
+import getDashboard from 'api/v1/dashboards/id/get';
+import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
+import ROUTES from 'constants/routes';
+import { DashboardProvider, useDashboard } from 'providers/Dashboard/Dashboard';
+import { QueryClient, QueryClientProvider } from 'react-query';
+import { MemoryRouter } from 'react-router-dom';
+
+// Mock the dashboard API
+jest.mock('api/v1/dashboards/id/get');
+jest.mock('api/v1/dashboards/id/lock');
+const mockGetDashboard = jest.mocked(getDashboard);
+
+// Mock useRouteMatch to simulate different route scenarios
+const mockUseRouteMatch = jest.fn();
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
+ useRouteMatch: (): any => mockUseRouteMatch(),
+}));
+
+// Mock other dependencies
+jest.mock('hooks/useSafeNavigate', () => ({
+ useSafeNavigate: (): any => ({
+ safeNavigate: jest.fn(),
+ }),
+}));
+
+// Mock only the essential dependencies for Dashboard provider
+jest.mock('providers/App/App', () => ({
+ useAppContext: (): any => ({
+ isLoggedIn: true,
+ user: { email: 'test@example.com', role: 'ADMIN' },
+ }),
+}));
+
+jest.mock('providers/ErrorModalProvider', () => ({
+ useErrorModal: (): any => ({ showErrorModal: jest.fn() }),
+}));
+
+jest.mock('react-redux', () => ({
+ useSelector: jest.fn(() => ({
+ selectedTime: 'GLOBAL_TIME',
+ minTime: '2023-01-01T00:00:00Z',
+ maxTime: '2023-01-01T01:00:00Z',
+ })),
+ useDispatch: jest.fn(() => jest.fn()),
+}));
+
+jest.mock('uuid', () => ({ v4: jest.fn(() => 'mock-uuid') }));
+
+function TestComponent(): JSX.Element {
+ const { dashboardResponse, dashboardId } = useDashboard();
+
+ return (
+
+
{dashboardId}
+
{dashboardResponse.status}
+
{dashboardResponse.isLoading.toString()}
+
+ {dashboardResponse.isFetching.toString()}
+
+
+ );
+}
+
+// Helper to create a test query client
+function createTestQueryClient(): QueryClient {
+ return new QueryClient({
+ defaultOptions: {
+ queries: {
+ retry: false,
+ refetchOnWindowFocus: false,
+ },
+ },
+ });
+}
+
+// Helper to render with dashboard provider
+function renderWithDashboardProvider(
+ initialRoute = '/dashboard/test-dashboard-id',
+ routeMatchParams?: { dashboardId: string } | null,
+): any {
+ const queryClient = createTestQueryClient();
+
+ // Mock the route match
+ mockUseRouteMatch.mockReturnValue(
+ routeMatchParams
+ ? {
+ path: ROUTES.DASHBOARD,
+ url: `/dashboard/${routeMatchParams.dashboardId}`,
+ isExact: true,
+ params: routeMatchParams,
+ }
+ : null,
+ );
+
+ return render(
+
+
+
+
+
+
+ ,
+ );
+}
+
+describe('Dashboard Provider - Query Key with Route Params', () => {
+ const DASHBOARD_ID = 'test-dashboard-id';
+ const mockDashboardData = {
+ httpStatusCode: 200,
+ data: {
+ id: DASHBOARD_ID,
+ title: 'Test Dashboard',
+ description: 'Test Description',
+ tags: [],
+ data: {
+ title: 'Test Dashboard',
+ layout: [],
+ widgets: [],
+ variables: {},
+ panelMap: {},
+ },
+ createdAt: '2023-01-01T00:00:00Z',
+ updatedAt: '2023-01-01T00:00:00Z',
+ createdBy: 'test-user',
+ updatedBy: 'test-user',
+ locked: false,
+ },
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ mockGetDashboard.mockResolvedValue(mockDashboardData);
+ });
+
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+
+ describe('Query Key Behavior', () => {
+ it('should include route params in query key when on dashboard page', async () => {
+ const dashboardId = 'test-dashboard-id';
+ renderWithDashboardProvider(`/dashboard/${dashboardId}`, { dashboardId });
+
+ await waitFor(() => {
+ expect(mockGetDashboard).toHaveBeenCalledWith({ id: dashboardId });
+ });
+
+ // Verify the query was called with the correct parameters
+ expect(mockGetDashboard).toHaveBeenCalledTimes(1);
+ });
+
+ it('should refetch when route params change', async () => {
+ const initialDashboardId = 'initial-dashboard-id';
+ const newDashboardId = 'new-dashboard-id';
+
+ // First render with initial dashboard ID
+ const { rerender } = renderWithDashboardProvider(
+ `/dashboard/${initialDashboardId}`,
+ {
+ dashboardId: initialDashboardId,
+ },
+ );
+
+ await waitFor(() => {
+ expect(mockGetDashboard).toHaveBeenCalledWith({ id: initialDashboardId });
+ });
+
+ // Change route params to simulate navigation
+ mockUseRouteMatch.mockReturnValue({
+ path: ROUTES.DASHBOARD,
+ url: `/dashboard/${newDashboardId}`,
+ isExact: true,
+ params: { dashboardId: newDashboardId },
+ });
+
+ // Rerender with new route
+ rerender(
+
+
+
+
+
+
+ ,
+ );
+
+ await waitFor(() => {
+ expect(mockGetDashboard).toHaveBeenCalledWith({ id: newDashboardId });
+ });
+
+ // Should have been called twice - once for each dashboard ID
+ expect(mockGetDashboard).toHaveBeenCalledTimes(2);
+ });
+
+ it('should not fetch when not on dashboard page', () => {
+ // Mock no route match (not on dashboard page)
+ mockUseRouteMatch.mockReturnValue(null);
+
+ renderWithDashboardProvider('/some-other-page', null);
+
+ // Should not call the API
+ expect(mockGetDashboard).not.toHaveBeenCalled();
+ });
+
+ it('should handle undefined route params gracefully', async () => {
+ // Mock route match with undefined params
+ mockUseRouteMatch.mockReturnValue({
+ path: ROUTES.DASHBOARD,
+ url: '/dashboard/undefined',
+ isExact: true,
+ params: undefined,
+ });
+
+ renderWithDashboardProvider('/dashboard/undefined');
+
+ // Should not call API when params are undefined
+ expect(mockGetDashboard).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('Cache Behavior', () => {
+ it('should create separate cache entries for different route params', async () => {
+ const queryClient = createTestQueryClient();
+ const dashboardId1 = 'dashboard-1';
+ const dashboardId2 = 'dashboard-2';
+
+ // First dashboard
+ mockUseRouteMatch.mockReturnValue({
+ path: ROUTES.DASHBOARD,
+ url: `/dashboard/${dashboardId1}`,
+ isExact: true,
+ params: { dashboardId: dashboardId1 },
+ });
+
+ const { rerender } = render(
+
+
+
+
+
+
+ ,
+ );
+
+ await waitFor(() => {
+ expect(mockGetDashboard).toHaveBeenCalledWith({ id: dashboardId1 });
+ });
+
+ // Second dashboard
+ mockUseRouteMatch.mockReturnValue({
+ path: ROUTES.DASHBOARD,
+ url: `/dashboard/${dashboardId2}`,
+ isExact: true,
+ params: { dashboardId: dashboardId2 },
+ });
+
+ rerender(
+
+
+
+
+
+
+ ,
+ );
+
+ await waitFor(() => {
+ expect(mockGetDashboard).toHaveBeenCalledWith({ id: dashboardId2 });
+ });
+
+ // Should have separate cache entries
+ const cacheKeys = queryClient
+ .getQueryCache()
+ .getAll()
+ .map((query) => query.queryKey);
+ expect(cacheKeys).toHaveLength(2);
+ expect(cacheKeys[0]).toEqual([
+ REACT_QUERY_KEY.DASHBOARD_BY_ID,
+ { dashboardId: dashboardId1 },
+ dashboardId1,
+ ]);
+ expect(cacheKeys[1]).toEqual([
+ REACT_QUERY_KEY.DASHBOARD_BY_ID,
+ { dashboardId: dashboardId2 },
+ dashboardId2,
+ ]);
+ });
+ });
+});