Chore: Refactor packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail to TS (#59850)

This commit is contained in:
Hamas Shafiq
2022-12-12 17:08:01 +00:00
committed by GitHub
parent 5424ec4157
commit dfed68feed
12 changed files with 43 additions and 42 deletions

View File

@ -15,14 +15,14 @@
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import React from 'react'; import React from 'react';
import AccordianKeyValues, { KeyValuesSummary } from './AccordianKeyValues'; import AccordianKeyValues, { KeyValuesSummary, AccordianKeyValuesProps } from './AccordianKeyValues';
const tags = [ const tags = [
{ key: 'span.kind', value: 'client' }, { key: 'span.kind', value: 'client' },
{ key: 'omg', value: 'mos-def' }, { key: 'omg', value: 'mos-def' },
]; ];
const setupAccordian = (propOverrides) => { const setupAccordian = (propOverrides?: AccordianKeyValuesProps) => {
const props = { const props = {
compact: false, compact: false,
data: tags, data: tags,
@ -31,10 +31,10 @@ const setupAccordian = (propOverrides) => {
onToggle: jest.fn(), onToggle: jest.fn(),
...propOverrides, ...propOverrides,
}; };
return render(<AccordianKeyValues {...props} />); return render(<AccordianKeyValues {...(props as AccordianKeyValuesProps)} />);
}; };
const setupKeyValues = (propOverrides) => { const setupKeyValues = (propOverrides?: AccordianKeyValuesProps) => {
const props = { const props = {
data: tags, data: tags,
...propOverrides, ...propOverrides,
@ -48,7 +48,7 @@ describe('KeyValuesSummary tests', () => {
}); });
it('returns `null` when props.data is empty', () => { it('returns `null` when props.data is empty', () => {
setupKeyValues({ data: null }); setupKeyValues({ data: null } as unknown as AccordianKeyValuesProps);
expect(screen.queryAllByRole('table')).toHaveLength(0); expect(screen.queryAllByRole('table')).toHaveLength(0);
expect(screen.queryAllByRole('row')).toHaveLength(0); expect(screen.queryAllByRole('row')).toHaveLength(0);
@ -95,7 +95,7 @@ describe('AccordianKeyValues test', () => {
}); });
it('renders the summary instead of the table when it is not expanded', () => { it('renders the summary instead of the table when it is not expanded', () => {
setupAccordian({ isOpen: false }); setupAccordian({ isOpen: false } as AccordianKeyValuesProps);
expect( expect(
screen.getByRole('switch', { name: 'test accordian: span.kind = client omg = mos-def' }) screen.getByRole('switch', { name: 'test accordian: span.kind = client omg = mos-def' })

View File

@ -86,7 +86,7 @@ export const getStyles = (theme: GrafanaTheme2) => {
}; };
}; };
type AccordianKeyValuesProps = { export type AccordianKeyValuesProps = {
className?: string | TNil; className?: string | TNil;
data: TraceKeyValuePair[]; data: TraceKeyValuePair[];
highContrast?: boolean; highContrast?: boolean;

View File

@ -15,7 +15,7 @@
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import React from 'react'; import React from 'react';
import AccordianLogs from './AccordianLogs'; import AccordianLogs, { AccordianLogsProps } from './AccordianLogs';
const logs = [ const logs = [
{ {
@ -34,7 +34,7 @@ const logs = [
}, },
]; ];
const setup = (propOverrides) => { const setup = (propOverrides?: AccordianLogsProps) => {
const props = { const props = {
logs, logs,
isOpen: false, isOpen: false,
@ -60,13 +60,13 @@ describe('AccordianLogs tests', () => {
}); });
it('hides log entries when not expanded', () => { it('hides log entries when not expanded', () => {
setup({ isOpen: false }); setup({ isOpen: false } as AccordianLogsProps);
expect(screen.queryByRole('table')).not.toBeInTheDocument(); expect(screen.queryByRole('table')).not.toBeInTheDocument();
}); });
it('shows log entries when expanded', () => { it('shows log entries when expanded', () => {
setup({ isOpen: true }); setup({ isOpen: true } as AccordianLogsProps);
expect(screen.getByRole('table')).toBeInTheDocument(); expect(screen.getByRole('table')).toBeInTheDocument();
expect(screen.queryAllByRole('cell')).toHaveLength(6); expect(screen.queryAllByRole('cell')).toHaveLength(6);

View File

@ -60,7 +60,7 @@ const getStyles = (theme: GrafanaTheme2) => {
}; };
}; };
type AccordianLogsProps = { export type AccordianLogsProps = {
interactive?: boolean; interactive?: boolean;
isOpen: boolean; isOpen: boolean;
linksGetter: ((pairs: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil; linksGetter: ((pairs: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil;

View File

@ -15,7 +15,7 @@
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import React from 'react'; import React from 'react';
import AccordianReferences, { References } from './AccordianReferences'; import AccordianReferences, { AccordianReferencesProps } from './AccordianReferences';
const traceID = 'trace1'; const traceID = 'trace1';
const references = [ const references = [
@ -54,7 +54,7 @@ const references = [
const link = { href: 'link' }; const link = { href: 'link' };
const setup = (propOverrides) => { const setup = (propOverrides?: AccordianReferencesProps) => {
const props = { const props = {
compact: false, compact: false,
data: references, data: references,
@ -65,7 +65,7 @@ const setup = (propOverrides) => {
...propOverrides, ...propOverrides,
}; };
return render(<AccordianReferences {...props} />); return render(<AccordianReferences {...(props as AccordianReferencesProps)} />);
}; };
describe('AccordianReferences tests', () => { describe('AccordianReferences tests', () => {
@ -80,14 +80,14 @@ describe('AccordianReferences tests', () => {
}); });
it('content doesnt show when not expanded', () => { it('content doesnt show when not expanded', () => {
setup({ isOpen: false }); setup({ isOpen: false } as AccordianReferencesProps);
expect(screen.queryByRole('link', { name: /^View\sLinked/ })).not.toBeInTheDocument(); expect(screen.queryByRole('link', { name: /^View\sLinked/ })).not.toBeInTheDocument();
expect(screen.queryAllByRole('link', { name: /^service\d\sop\d/ })).toHaveLength(0); expect(screen.queryAllByRole('link', { name: /^service\d\sop\d/ })).toHaveLength(0);
}); });
it('renders the content when it is expanded', () => { it('renders the content when it is expanded', () => {
setup({ isOpen: true }); setup({ isOpen: true } as AccordianReferencesProps);
expect(screen.getByRole('switch', { name: 'References (3)' })).toBeInTheDocument(); expect(screen.getByRole('switch', { name: 'References (3)' })).toBeInTheDocument();
expect(screen.getAllByRole('link', { name: /^service\d\sop\d/ })).toHaveLength(2); expect(screen.getAllByRole('link', { name: /^service\d\sop\d/ })).toHaveLength(2);

View File

@ -111,7 +111,7 @@ const getStyles = (theme: GrafanaTheme2) => {
}; };
}; };
type AccordianReferencesProps = { export type AccordianReferencesProps = {
data: TraceSpanReference[]; data: TraceSpanReference[];
highContrast?: boolean; highContrast?: boolean;
interactive?: boolean; interactive?: boolean;

View File

@ -15,7 +15,7 @@
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import React from 'react'; import React from 'react';
import KeyValuesTable, { LinkValue } from './KeyValuesTable'; import KeyValuesTable, { LinkValue, KeyValuesTableProps } from './KeyValuesTable';
const data = [ const data = [
{ key: 'span.kind', value: 'client' }, { key: 'span.kind', value: 'client' },
@ -24,12 +24,12 @@ const data = [
{ key: 'jsonkey', value: JSON.stringify({ hello: 'world' }) }, { key: 'jsonkey', value: JSON.stringify({ hello: 'world' }) },
]; ];
const setup = (propOverrides) => { const setup = (propOverrides?: KeyValuesTableProps) => {
const props = { const props = {
data: data, data: data,
...propOverrides, ...propOverrides,
}; };
return render(<KeyValuesTable {...props} />); return render(<KeyValuesTable {...(props as KeyValuesTableProps)} />);
}; };
describe('LinkValue', () => { describe('LinkValue', () => {
@ -79,7 +79,7 @@ describe('KeyValuesTable tests', () => {
}, },
] ]
: [], : [],
}); } as KeyValuesTableProps);
expect(screen.getByRole('row', { name: 'span.kind More info about client' })).toBeInTheDocument(); expect(screen.getByRole('row', { name: 'span.kind More info about client' })).toBeInTheDocument();
}); });

View File

@ -99,7 +99,7 @@ LinkValue.defaultProps = {
title: '', title: '',
}; };
type KeyValuesTableProps = { export type KeyValuesTableProps = {
data: TraceKeyValuePair[]; data: TraceKeyValuePair[];
linksGetter: ((pairs: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil; linksGetter: ((pairs: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil;
}; };

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { render, screen, within } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import React from 'react'; import React from 'react';
import TextList from './TextList'; import TextList from './TextList';

View File

@ -17,6 +17,7 @@ jest.mock('../utils');
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import React from 'react'; import React from 'react';
import { TraceSpanReference } from 'src/types/trace';
import traceGenerator from '../../demo/trace-generators'; import traceGenerator from '../../demo/trace-generators';
import transformTraceData from '../../model/transform-trace-data'; import transformTraceData from '../../model/transform-trace-data';
@ -24,11 +25,11 @@ import { formatDuration } from '../utils';
import DetailState from './DetailState'; import DetailState from './DetailState';
import SpanDetail, { getAbsoluteTime } from './index'; import SpanDetail, { getAbsoluteTime, SpanDetailProps } from './index';
describe('<SpanDetail>', () => { describe('<SpanDetail>', () => {
// use `transformTraceData` on a fake trace to get a fully processed span // use `transformTraceData` on a fake trace to get a fully processed span
const span = transformTraceData(traceGenerator.trace({ numberOfSpans: 1 })).spans[0]; const span = transformTraceData(traceGenerator.trace({ numberOfSpans: 1 }))!.spans[0];
const detailState = new DetailState().toggleLogs().toggleProcess().toggleReferences().toggleTags(); const detailState = new DetailState().toggleLogs().toggleProcess().toggleReferences().toggleTags();
const traceStartTime = 5; const traceStartTime = 5;
const topOfExploreViewRef = jest.fn(); const topOfExploreViewRef = jest.fn();
@ -78,7 +79,7 @@ describe('<SpanDetail>', () => {
}, },
spanID: 'span1', spanID: 'span1',
traceID: 'trace1', traceID: 'trace1',
}, } as TraceSpanReference,
{ {
refType: 'CHILD_OF', refType: 'CHILD_OF',
span: { span: {
@ -91,7 +92,7 @@ describe('<SpanDetail>', () => {
}, },
spanID: 'span4', spanID: 'span4',
traceID: 'trace1', traceID: 'trace1',
}, } as TraceSpanReference,
{ {
refType: 'CHILD_OF', refType: 'CHILD_OF',
span: { span: {
@ -104,11 +105,11 @@ describe('<SpanDetail>', () => {
}, },
spanID: 'span5', spanID: 'span5',
traceID: 'trace2', traceID: 'trace2',
}, } as TraceSpanReference,
]; ];
beforeEach(() => { beforeEach(() => {
formatDuration.mockReset(); jest.mocked(formatDuration).mockReset();
props.tagsToggle.mockReset(); props.tagsToggle.mockReset();
props.processToggle.mockReset(); props.processToggle.mockReset();
props.logsToggle.mockReset(); props.logsToggle.mockReset();
@ -116,24 +117,24 @@ describe('<SpanDetail>', () => {
}); });
it('renders without exploding', () => { it('renders without exploding', () => {
expect(() => render(<SpanDetail {...props} />)).not.toThrow(); expect(() => render(<SpanDetail {...(props as unknown as SpanDetailProps)} />)).not.toThrow();
}); });
it('shows the operation name', () => { it('shows the operation name', () => {
render(<SpanDetail {...props} />); render(<SpanDetail {...(props as unknown as SpanDetailProps)} />);
expect(screen.getByRole('heading', { name: span.operationName })).toBeInTheDocument(); expect(screen.getByRole('heading', { name: span.operationName })).toBeInTheDocument();
}); });
it('lists the service name, duration and start time', () => { it('lists the service name, duration and start time', () => {
render(<SpanDetail {...props} />); render(<SpanDetail {...(props as unknown as SpanDetailProps)} />);
expect(screen.getByText('Duration:')).toBeInTheDocument(); expect(screen.getByText('Duration:')).toBeInTheDocument();
expect(screen.getByText('Service:')).toBeInTheDocument(); expect(screen.getByText('Service:')).toBeInTheDocument();
expect(screen.getByText('Start Time:')).toBeInTheDocument(); expect(screen.getByText('Start Time:')).toBeInTheDocument();
}); });
it('start time shows the absolute time', () => { it('start time shows the absolute time', () => {
render(<SpanDetail {...props} />); render(<SpanDetail {...(props as unknown as SpanDetailProps)} />);
const absoluteTime = getAbsoluteTime(span.startTime); const absoluteTime = getAbsoluteTime(span.startTime, 'browser');
expect( expect(
screen.getByText((text) => { screen.getByText((text) => {
return text.includes(absoluteTime); return text.includes(absoluteTime);
@ -142,19 +143,19 @@ describe('<SpanDetail>', () => {
}); });
it('renders the span tags', async () => { it('renders the span tags', async () => {
render(<SpanDetail {...props} />); render(<SpanDetail {...(props as unknown as SpanDetailProps)} />);
await userEvent.click(screen.getByRole('switch', { name: /Attributes/ })); await userEvent.click(screen.getByRole('switch', { name: /Attributes/ }));
expect(props.tagsToggle).toHaveBeenLastCalledWith(span.spanID); expect(props.tagsToggle).toHaveBeenLastCalledWith(span.spanID);
}); });
it('renders the process tags', async () => { it('renders the process tags', async () => {
render(<SpanDetail {...props} />); render(<SpanDetail {...(props as unknown as SpanDetailProps)} />);
await userEvent.click(screen.getByRole('switch', { name: /Resource/ })); await userEvent.click(screen.getByRole('switch', { name: /Resource/ }));
expect(props.processToggle).toHaveBeenLastCalledWith(span.spanID); expect(props.processToggle).toHaveBeenLastCalledWith(span.spanID);
}); });
it('renders the logs', async () => { it('renders the logs', async () => {
render(<SpanDetail {...props} />); render(<SpanDetail {...(props as unknown as SpanDetailProps)} />);
await userEvent.click(screen.getByRole('switch', { name: /Events/ })); await userEvent.click(screen.getByRole('switch', { name: /Events/ }));
expect(props.logsToggle).toHaveBeenLastCalledWith(span.spanID); expect(props.logsToggle).toHaveBeenLastCalledWith(span.spanID);
await userEvent.click(screen.getByRole('switch', { name: /oh the log/ })); await userEvent.click(screen.getByRole('switch', { name: /oh the log/ }));
@ -162,19 +163,19 @@ describe('<SpanDetail>', () => {
}); });
it('renders the warnings', async () => { it('renders the warnings', async () => {
render(<SpanDetail {...props} />); render(<SpanDetail {...(props as unknown as SpanDetailProps)} />);
await userEvent.click(screen.getByRole('switch', { name: /Warnings/ })); await userEvent.click(screen.getByRole('switch', { name: /Warnings/ }));
expect(props.warningsToggle).toHaveBeenLastCalledWith(span.spanID); expect(props.warningsToggle).toHaveBeenLastCalledWith(span.spanID);
}); });
it('renders the references', async () => { it('renders the references', async () => {
render(<SpanDetail {...props} />); render(<SpanDetail {...(props as unknown as SpanDetailProps)} />);
await userEvent.click(screen.getByRole('switch', { name: /References/ })); await userEvent.click(screen.getByRole('switch', { name: /References/ }));
expect(props.referencesToggle).toHaveBeenLastCalledWith(span.spanID); expect(props.referencesToggle).toHaveBeenLastCalledWith(span.spanID);
}); });
it('renders deep link URL', () => { it('renders deep link URL', () => {
render(<SpanDetail {...props} />); render(<SpanDetail {...(props as unknown as SpanDetailProps)} />);
expect(document.getElementsByTagName('a').length).toBeGreaterThan(1); expect(document.getElementsByTagName('a').length).toBeGreaterThan(1);
}); });
}); });

View File

@ -103,7 +103,7 @@ const getStyles = (theme: GrafanaTheme2) => {
}; };
}; };
type SpanDetailProps = { export type SpanDetailProps = {
detailState: DetailState; detailState: DetailState;
linksGetter: ((links: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil; linksGetter: ((links: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil;
logItemToggle: (spanID: string, log: TraceLog) => void; logItemToggle: (spanID: string, log: TraceLog) => void;