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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 43 additions and 42 deletions

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@
import { render, screen } from '@testing-library/react';
import React from 'react';
import AccordianReferences, { References } from './AccordianReferences';
import AccordianReferences, { AccordianReferencesProps } from './AccordianReferences';
const traceID = 'trace1';
const references = [
@ -54,7 +54,7 @@ const references = [
const link = { href: 'link' };
const setup = (propOverrides) => {
const setup = (propOverrides?: AccordianReferencesProps) => {
const props = {
compact: false,
data: references,
@ -65,7 +65,7 @@ const setup = (propOverrides) => {
...propOverrides,
};
return render(<AccordianReferences {...props} />);
return render(<AccordianReferences {...(props as AccordianReferencesProps)} />);
};
describe('AccordianReferences tests', () => {
@ -80,14 +80,14 @@ describe('AccordianReferences tests', () => {
});
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.queryAllByRole('link', { name: /^service\d\sop\d/ })).toHaveLength(0);
});
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.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[];
highContrast?: boolean;
interactive?: boolean;

View File

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

View File

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

View File

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

View File

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

View File

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