mirror of
https://github.com/SigNoz/signoz.git
synced 2026-05-07 02:50:31 +01:00
Compare commits
3 Commits
issue_4361
...
fix/lint-s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8554af8b00 | ||
|
|
72036b42e3 | ||
|
|
9301b2fb1c |
@@ -239,10 +239,12 @@
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(js|jsx|ts|tsx)": [
|
||||
"oxlint --fix",
|
||||
"oxfmt --write",
|
||||
"sh -c tsgo --noEmit"
|
||||
],
|
||||
"*.(js|jsx|ts|tsx|scss|css)": [
|
||||
"oxlint --fix --quiet --no-error-on-unmatched-pattern",
|
||||
"oxfmt --write"
|
||||
],
|
||||
"*.(scss|css)": [
|
||||
"stylelint"
|
||||
]
|
||||
|
||||
158
frontend/src/hooks/dashboard/useDashboardBootstrap.test.tsx
Normal file
158
frontend/src/hooks/dashboard/useDashboardBootstrap.test.tsx
Normal file
@@ -0,0 +1,158 @@
|
||||
import { act, render } from '@testing-library/react';
|
||||
import { Modal } from 'antd';
|
||||
import { useDashboardBootstrap } from 'hooks/dashboard/useDashboardBootstrap';
|
||||
import { useTransformDashboardVariables } from 'hooks/dashboard/useTransformDashboardVariables';
|
||||
import useTabVisibility from 'hooks/useTabFocus';
|
||||
import { getMinMaxForSelectedTime } from 'lib/getMinMax';
|
||||
import { useDashboardStore } from 'providers/Dashboard/store/useDashboardStore';
|
||||
import { useDashboardQuery } from './useDashboardQuery';
|
||||
|
||||
const mockDispatch = jest.fn();
|
||||
const mockSetDashboardData = jest.fn();
|
||||
const mockSetLayouts = jest.fn();
|
||||
const mockSetPanelMap = jest.fn();
|
||||
const mockResetDashboardStore = jest.fn();
|
||||
const mockGetUrlVariables = jest.fn();
|
||||
const mockUpdateUrlVariable = jest.fn();
|
||||
const mockRefetch = jest.fn();
|
||||
|
||||
let mockGlobalTime = {
|
||||
selectedTime: 'custom',
|
||||
minTime: 1710000000000000000,
|
||||
maxTime: 1710000300000000000,
|
||||
isAutoRefreshDisabled: true,
|
||||
};
|
||||
|
||||
let currentQueryData: unknown;
|
||||
|
||||
jest.mock('react-i18next', () => ({
|
||||
useTranslation: (): { t: (key: string) => string } => ({
|
||||
t: (key: string): string => key,
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('react-redux', () => ({
|
||||
useDispatch: jest.fn(() => mockDispatch),
|
||||
useSelector: jest.fn(
|
||||
(
|
||||
selectorFn: (state: { globalTime: typeof mockGlobalTime }) => unknown,
|
||||
): unknown => selectorFn({ globalTime: mockGlobalTime }),
|
||||
),
|
||||
}));
|
||||
|
||||
jest.mock('hooks/useTabFocus', () => jest.fn(() => true));
|
||||
jest.mock('hooks/dashboard/useDashboardVariablesSync', () => ({
|
||||
useDashboardVariablesSync: jest.fn(),
|
||||
}));
|
||||
jest.mock('./useDashboardQuery', () => ({
|
||||
useDashboardQuery: jest.fn(),
|
||||
}));
|
||||
jest.mock('hooks/dashboard/useTransformDashboardVariables', () => ({
|
||||
useTransformDashboardVariables: jest.fn(),
|
||||
}));
|
||||
jest.mock('providers/Dashboard/store/useDashboardStore', () => ({
|
||||
useDashboardStore: jest.fn(),
|
||||
}));
|
||||
jest.mock('providers/Dashboard/initializeDefaultVariables', () => ({
|
||||
initializeDefaultVariables: jest.fn(),
|
||||
}));
|
||||
jest.mock('lib/dashboard/getUpdatedLayout', () => ({
|
||||
getUpdatedLayout: jest.fn(() => []),
|
||||
}));
|
||||
jest.mock('providers/Dashboard/util', () => ({
|
||||
sortLayout: jest.fn((layout) => layout),
|
||||
}));
|
||||
jest.mock('lib/getMinMax', () => ({
|
||||
getMinMaxForSelectedTime: jest.fn(),
|
||||
}));
|
||||
|
||||
function TestComponent({ confirm }: { confirm: typeof Modal.confirm }): null {
|
||||
useDashboardBootstrap('dashboard-1', { confirm });
|
||||
return null;
|
||||
}
|
||||
|
||||
describe('useDashboardBootstrap', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
mockGlobalTime = {
|
||||
selectedTime: 'custom',
|
||||
minTime: 1710000000000000000,
|
||||
maxTime: 1710000300000000000,
|
||||
isAutoRefreshDisabled: true,
|
||||
};
|
||||
|
||||
jest.mocked(useDashboardStore as unknown as jest.Mock).mockReturnValue({
|
||||
setDashboardData: mockSetDashboardData,
|
||||
setLayouts: mockSetLayouts,
|
||||
setPanelMap: mockSetPanelMap,
|
||||
resetDashboardStore: mockResetDashboardStore,
|
||||
});
|
||||
|
||||
jest
|
||||
.mocked(useTransformDashboardVariables as unknown as jest.Mock)
|
||||
.mockReturnValue({
|
||||
getUrlVariables: mockGetUrlVariables,
|
||||
updateUrlVariable: mockUpdateUrlVariable,
|
||||
transformDashboardVariables: <T,>(data: T): T => data,
|
||||
});
|
||||
|
||||
jest.mocked(useTabVisibility as unknown as jest.Mock).mockReturnValue(true);
|
||||
jest
|
||||
.mocked(useDashboardQuery as unknown as jest.Mock)
|
||||
.mockImplementation(() => ({
|
||||
data: currentQueryData,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
isFetching: false,
|
||||
error: null,
|
||||
refetch: mockRefetch,
|
||||
}));
|
||||
});
|
||||
|
||||
it('keeps minTime and maxTime unchanged for custom range on refresh confirm', () => {
|
||||
const initialDashboard = {
|
||||
id: 'dashboard-1',
|
||||
updatedAt: '2024-01-01T00:00:00.000Z',
|
||||
data: { layout: [], panelMap: {}, variables: {} },
|
||||
};
|
||||
|
||||
const updatedDashboard = {
|
||||
id: 'dashboard-1',
|
||||
updatedAt: '2024-01-01T01:00:00.000Z',
|
||||
data: { layout: [], panelMap: {}, variables: {} },
|
||||
};
|
||||
|
||||
const mockConfirm = jest.fn<
|
||||
ReturnType<typeof Modal.confirm>,
|
||||
Parameters<typeof Modal.confirm>
|
||||
>(() => ({ destroy: jest.fn(), update: jest.fn() }));
|
||||
|
||||
currentQueryData = { data: initialDashboard };
|
||||
const { rerender } = render(<TestComponent confirm={mockConfirm} />);
|
||||
|
||||
expect(mockConfirm).not.toHaveBeenCalled();
|
||||
|
||||
currentQueryData = { data: updatedDashboard };
|
||||
rerender(<TestComponent confirm={mockConfirm} />);
|
||||
|
||||
expect(mockConfirm).toHaveBeenCalledTimes(1);
|
||||
const firstCall = mockConfirm.mock.calls[0];
|
||||
expect(firstCall).toBeDefined();
|
||||
const [confirmProps] = firstCall as Parameters<typeof Modal.confirm>;
|
||||
|
||||
act(() => {
|
||||
confirmProps.onOk?.();
|
||||
});
|
||||
|
||||
expect(getMinMaxForSelectedTime).not.toHaveBeenCalled();
|
||||
expect(mockDispatch).toHaveBeenCalledWith({
|
||||
type: 'UPDATE_TIME_INTERVAL',
|
||||
payload: {
|
||||
selectedTime: 'custom',
|
||||
minTime: mockGlobalTime.minTime,
|
||||
maxTime: mockGlobalTime.maxTime,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -102,11 +102,19 @@ export function useDashboardBootstrap(
|
||||
onOk() {
|
||||
setDashboardData(updatedDashboardData);
|
||||
|
||||
const { maxTime, minTime } = getMinMaxForSelectedTime(
|
||||
globalTime.selectedTime,
|
||||
globalTime.minTime,
|
||||
globalTime.maxTime,
|
||||
);
|
||||
const { maxTime, minTime } =
|
||||
globalTime.selectedTime === 'custom'
|
||||
? {
|
||||
// For custom ranges, min/max are already stored in nanoseconds.
|
||||
// Recomputing via getMinMaxForSelectedTime would multiply them again.
|
||||
maxTime: globalTime.maxTime,
|
||||
minTime: globalTime.minTime,
|
||||
}
|
||||
: getMinMaxForSelectedTime(
|
||||
globalTime.selectedTime,
|
||||
globalTime.minTime,
|
||||
globalTime.maxTime,
|
||||
);
|
||||
dispatch({
|
||||
type: UPDATE_TIME_INTERVAL,
|
||||
payload: { maxTime, minTime, selectedTime: globalTime.selectedTime },
|
||||
|
||||
@@ -7,7 +7,12 @@ export const topTracesTableColumns = [
|
||||
dataIndex: 'trace_id',
|
||||
key: 'trace_id',
|
||||
render: (traceId: string): JSX.Element => (
|
||||
<Link to={`/trace/${traceId}`} className="trace-id-cell">
|
||||
<Link
|
||||
to={`/trace/${traceId}`}
|
||||
className="trace-id-cell"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{traceId}
|
||||
</Link>
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user