mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 18:59:10 +08:00
feat: added test cases for copy span link functionality
This commit is contained in:
parent
afb18b8142
commit
2a5c7cc0ab
@ -0,0 +1,90 @@
|
|||||||
|
import { fireEvent, screen } from '@testing-library/react';
|
||||||
|
import { useCopySpanLink } from 'hooks/trace/useCopySpanLink';
|
||||||
|
import { render } from 'tests/test-utils';
|
||||||
|
import { Span } from 'types/api/trace/getTraceV2';
|
||||||
|
|
||||||
|
import SpanLineActionButtons from '../index';
|
||||||
|
|
||||||
|
// Mock the useCopySpanLink hook
|
||||||
|
jest.mock('hooks/trace/useCopySpanLink');
|
||||||
|
|
||||||
|
const mockSpan: Span = {
|
||||||
|
spanId: 'test-span-id',
|
||||||
|
name: 'test-span',
|
||||||
|
serviceName: 'test-service',
|
||||||
|
durationNano: 1000,
|
||||||
|
timestamp: 1234567890,
|
||||||
|
rootSpanId: 'test-root-span-id',
|
||||||
|
parentSpanId: 'test-parent-span-id',
|
||||||
|
traceId: 'test-trace-id',
|
||||||
|
hasError: false,
|
||||||
|
kind: 0,
|
||||||
|
references: [],
|
||||||
|
tagMap: {},
|
||||||
|
event: [],
|
||||||
|
rootName: 'test-root-name',
|
||||||
|
statusMessage: 'test-status-message',
|
||||||
|
statusCodeString: 'test-status-code-string',
|
||||||
|
spanKind: 'test-span-kind',
|
||||||
|
hasChildren: false,
|
||||||
|
hasSibling: false,
|
||||||
|
subTreeNodeCount: 0,
|
||||||
|
level: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('SpanLineActionButtons', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Clear mock before each test
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders copy link button with correct icon', () => {
|
||||||
|
(useCopySpanLink as jest.Mock).mockReturnValue({
|
||||||
|
onSpanCopy: jest.fn(),
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<SpanLineActionButtons span={mockSpan} />);
|
||||||
|
|
||||||
|
// Check if the button is rendered
|
||||||
|
const copyButton = screen.getByRole('button');
|
||||||
|
expect(copyButton).toBeInTheDocument();
|
||||||
|
|
||||||
|
// Check if the link icon is rendered
|
||||||
|
const linkIcon = screen.getByRole('img', { hidden: true });
|
||||||
|
expect(linkIcon).toHaveClass('anticon anticon-link');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls onSpanCopy when copy button is clicked', () => {
|
||||||
|
const mockOnSpanCopy = jest.fn();
|
||||||
|
(useCopySpanLink as jest.Mock).mockReturnValue({
|
||||||
|
onSpanCopy: mockOnSpanCopy,
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<SpanLineActionButtons span={mockSpan} />);
|
||||||
|
|
||||||
|
// Click the copy button
|
||||||
|
const copyButton = screen.getByRole('button');
|
||||||
|
fireEvent.click(copyButton);
|
||||||
|
|
||||||
|
// Verify the copy function was called
|
||||||
|
expect(mockOnSpanCopy).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies correct styling classes', () => {
|
||||||
|
(useCopySpanLink as jest.Mock).mockReturnValue({
|
||||||
|
onSpanCopy: jest.fn(),
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<SpanLineActionButtons span={mockSpan} />);
|
||||||
|
|
||||||
|
// Check if the main container has the correct class
|
||||||
|
const container = screen
|
||||||
|
.getByRole('button')
|
||||||
|
.closest('.span-line-action-buttons');
|
||||||
|
expect(container).toHaveClass('span-line-action-buttons');
|
||||||
|
|
||||||
|
// Check if the button has the correct class
|
||||||
|
const copyButton = screen.getByRole('button');
|
||||||
|
expect(copyButton).toHaveClass('copy-span-btn');
|
||||||
|
});
|
||||||
|
});
|
@ -151,7 +151,7 @@ function SpanOverview({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SpanDuration({
|
export function SpanDuration({
|
||||||
span,
|
span,
|
||||||
traceMetadata,
|
traceMetadata,
|
||||||
setSelectedSpan,
|
setSelectedSpan,
|
||||||
|
@ -0,0 +1,131 @@
|
|||||||
|
import { fireEvent, screen } from '@testing-library/react';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import { render } from 'tests/test-utils';
|
||||||
|
import { Span } from 'types/api/trace/getTraceV2';
|
||||||
|
|
||||||
|
import { SpanDuration } from '../Success';
|
||||||
|
|
||||||
|
// Mock the hooks
|
||||||
|
jest.mock('hooks/useSafeNavigate');
|
||||||
|
jest.mock('hooks/useUrlQuery');
|
||||||
|
|
||||||
|
const mockSpan: Span = {
|
||||||
|
spanId: 'test-span-id',
|
||||||
|
name: 'test-span',
|
||||||
|
serviceName: 'test-service',
|
||||||
|
durationNano: 1160000, // 1ms in nano
|
||||||
|
timestamp: 1234567890,
|
||||||
|
rootSpanId: 'test-root-span-id',
|
||||||
|
parentSpanId: 'test-parent-span-id',
|
||||||
|
traceId: 'test-trace-id',
|
||||||
|
hasError: false,
|
||||||
|
kind: 0,
|
||||||
|
references: [],
|
||||||
|
tagMap: {},
|
||||||
|
event: [],
|
||||||
|
rootName: 'test-root-name',
|
||||||
|
statusMessage: 'test-status-message',
|
||||||
|
statusCodeString: 'test-status-code-string',
|
||||||
|
spanKind: 'test-span-kind',
|
||||||
|
hasChildren: false,
|
||||||
|
hasSibling: false,
|
||||||
|
subTreeNodeCount: 0,
|
||||||
|
level: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockTraceMetadata = {
|
||||||
|
traceId: 'test-trace-id',
|
||||||
|
startTime: 1234567000,
|
||||||
|
endTime: 1234569000,
|
||||||
|
hasMissingSpans: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('SpanDuration', () => {
|
||||||
|
const mockSetSelectedSpan = jest.fn();
|
||||||
|
const mockUrlQuerySet = jest.fn();
|
||||||
|
const mockSafeNavigate = jest.fn();
|
||||||
|
const mockUrlQueryGet = jest.fn();
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
|
||||||
|
// Mock URL query hook
|
||||||
|
(useUrlQuery as jest.Mock).mockReturnValue({
|
||||||
|
set: mockUrlQuerySet,
|
||||||
|
get: mockUrlQueryGet,
|
||||||
|
toString: () => 'spanId=test-span-id',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Mock safe navigate hook
|
||||||
|
(useSafeNavigate as jest.Mock).mockReturnValue({
|
||||||
|
safeNavigate: mockSafeNavigate,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates URL and selected span when clicked', () => {
|
||||||
|
render(
|
||||||
|
<SpanDuration
|
||||||
|
span={mockSpan}
|
||||||
|
traceMetadata={mockTraceMetadata}
|
||||||
|
selectedSpan={undefined}
|
||||||
|
setSelectedSpan={mockSetSelectedSpan}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Find and click the span duration element
|
||||||
|
const spanElement = screen.getByText('1.16 ms');
|
||||||
|
fireEvent.click(spanElement);
|
||||||
|
|
||||||
|
// Verify setSelectedSpan was called with the correct span
|
||||||
|
expect(mockSetSelectedSpan).toHaveBeenCalledWith(mockSpan);
|
||||||
|
|
||||||
|
// Verify URL query was updated
|
||||||
|
expect(mockUrlQuerySet).toHaveBeenCalledWith('spanId', 'test-span-id');
|
||||||
|
|
||||||
|
// Verify navigation was triggered
|
||||||
|
expect(mockSafeNavigate).toHaveBeenCalledWith({
|
||||||
|
search: 'spanId=test-span-id',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows action buttons on hover', () => {
|
||||||
|
render(
|
||||||
|
<SpanDuration
|
||||||
|
span={mockSpan}
|
||||||
|
traceMetadata={mockTraceMetadata}
|
||||||
|
selectedSpan={undefined}
|
||||||
|
setSelectedSpan={mockSetSelectedSpan}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
const spanElement = screen.getByText('1.16 ms');
|
||||||
|
|
||||||
|
// Initially, action buttons should not be visible
|
||||||
|
expect(screen.queryByRole('button')).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
// Hover over the span
|
||||||
|
fireEvent.mouseEnter(spanElement);
|
||||||
|
|
||||||
|
// Action buttons should now be visible
|
||||||
|
expect(screen.getByRole('button')).toBeInTheDocument();
|
||||||
|
|
||||||
|
// Mouse leave should hide the buttons
|
||||||
|
fireEvent.mouseLeave(spanElement);
|
||||||
|
expect(screen.queryByRole('button')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies interested-span class when span is selected', () => {
|
||||||
|
render(
|
||||||
|
<SpanDuration
|
||||||
|
span={mockSpan}
|
||||||
|
traceMetadata={mockTraceMetadata}
|
||||||
|
selectedSpan={mockSpan}
|
||||||
|
setSelectedSpan={mockSetSelectedSpan}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
const spanElement = screen.getByText('1.16 ms').closest('.span-duration');
|
||||||
|
expect(spanElement).toHaveClass('interested-span');
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user