Table: Add unit tests for MaybeWrapWithLink (#109932)
This commit is contained in:
@@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
||||
|
||||
import { formattedValueToString } from '@grafana/data';
|
||||
|
||||
import { MaybeWrapWithLink } from '../MaybeWrapWithLink';
|
||||
import { MaybeWrapWithLink } from '../components/MaybeWrapWithLink';
|
||||
import { AutoCellProps, TableCellStyles } from '../types';
|
||||
|
||||
export function AutoCell({ value, field, rowIdx }: AutoCellProps) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ThresholdsConfig, ThresholdsMode, VizOrientation, getFieldConfigWithMin
|
||||
import { BarGaugeDisplayMode, BarGaugeValueMode, TableCellDisplayMode } from '@grafana/schema';
|
||||
|
||||
import { BarGauge } from '../../../BarGauge/BarGauge';
|
||||
import { MaybeWrapWithLink } from '../MaybeWrapWithLink';
|
||||
import { MaybeWrapWithLink } from '../components/MaybeWrapWithLink';
|
||||
import { TABLE } from '../constants';
|
||||
import { BarGaugeCellProps } from '../types';
|
||||
import { getCellOptions, getAlignmentFactor } from '../utils';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { TableCellDisplayMode } from '../../types';
|
||||
import { MaybeWrapWithLink } from '../MaybeWrapWithLink';
|
||||
import { MaybeWrapWithLink } from '../components/MaybeWrapWithLink';
|
||||
import { ImageCellProps, TableCellStyles } from '../types';
|
||||
|
||||
export const ImageCell = ({ cellOptions, field, value, rowIdx }: ImageCellProps) => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
||||
|
||||
import { renderMarkdown } from '@grafana/data';
|
||||
|
||||
import { MaybeWrapWithLink } from '../MaybeWrapWithLink';
|
||||
import { MaybeWrapWithLink } from '../components/MaybeWrapWithLink';
|
||||
import { MarkdownCellProps, TableCellStyles } from '../types';
|
||||
|
||||
export function MarkdownCell({ field, rowIdx, disableSanitizeHtml }: MarkdownCellProps) {
|
||||
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { ActionType, Field, FieldType, HttpRequestMethod } from '@grafana/data';
|
||||
|
||||
import { MaybeWrapWithLink } from './MaybeWrapWithLink';
|
||||
|
||||
describe('MaybeWrapWithLink', () => {
|
||||
describe('single link', () => {
|
||||
it('renders children as a link when there is a single link', () => {
|
||||
const link = { title: 'My link', url: 'http://example.com' };
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => [{ title: link.title, href: link.url, target: '_blank', origin: field }]),
|
||||
config: {
|
||||
links: [link],
|
||||
actions: [],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
const linkElement = screen.getByTitle(link.title);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
expect(linkElement).toHaveAttribute('href', link.url);
|
||||
expect(linkElement).toHaveTextContent('Test Link');
|
||||
});
|
||||
|
||||
it('does not throw if getLinks unexpectedly returns nothing when a single link is present', () => {
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => []),
|
||||
config: {
|
||||
links: [{ title: 'My link', url: 'http://example.com' }],
|
||||
actions: [],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const childElement = screen.getByText('Test Link');
|
||||
expect(childElement).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('multi link and/or actions', () => {
|
||||
it('renders a popup target link if multiple links are present', () => {
|
||||
const links = [
|
||||
{ title: 'My link', url: 'http://example.com' },
|
||||
{ title: 'Another link', url: 'http://example.com' },
|
||||
];
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => links.map((l) => ({ title: l.title, href: l.url, target: '_blank', origin: field }))),
|
||||
config: {
|
||||
links,
|
||||
actions: [],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const linkElement = screen.getByTitle('view data links and actions');
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
expect(linkElement.tagName).toBe('A');
|
||||
expect(linkElement).toHaveAttribute('aria-haspopup', 'menu');
|
||||
expect(linkElement).toHaveTextContent('Test Link');
|
||||
});
|
||||
|
||||
it('renders a popup target link if multiple actions are present', () => {
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => []),
|
||||
config: {
|
||||
links: [],
|
||||
actions: [
|
||||
{
|
||||
type: ActionType.Fetch,
|
||||
title: 'My action',
|
||||
[ActionType.Fetch]: { method: HttpRequestMethod.GET, url: 'http://example.com' },
|
||||
},
|
||||
{
|
||||
type: ActionType.Fetch,
|
||||
title: 'Another action',
|
||||
[ActionType.Fetch]: { method: HttpRequestMethod.POST, url: 'http://example.com' },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const linkElement = screen.getByTitle('view data links and actions');
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
expect(linkElement.tagName).toBe('A');
|
||||
expect(linkElement).toHaveAttribute('aria-haspopup', 'menu');
|
||||
expect(linkElement).toHaveTextContent('Test Link');
|
||||
});
|
||||
|
||||
it('renders a popup target link if a single action is present', () => {
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => []),
|
||||
config: {
|
||||
links: [],
|
||||
actions: [
|
||||
{
|
||||
type: ActionType.Fetch,
|
||||
title: 'My action',
|
||||
[ActionType.Fetch]: { method: HttpRequestMethod.GET, url: 'http://example.com' },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const linkElement = screen.getByTitle('view data links and actions');
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
expect(linkElement.tagName).toBe('A');
|
||||
expect(linkElement).toHaveAttribute('aria-haspopup', 'menu');
|
||||
expect(linkElement).toHaveTextContent('Test Link');
|
||||
});
|
||||
|
||||
it('renders a popup target link if a mixture of actions and links are present', () => {
|
||||
const links = [{ title: 'My link', url: 'http://example.com' }];
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => links.map((l) => ({ title: l.title, href: l.url, target: '_blank', origin: field }))),
|
||||
config: {
|
||||
links,
|
||||
actions: [
|
||||
{
|
||||
type: ActionType.Fetch,
|
||||
title: 'My action',
|
||||
[ActionType.Fetch]: { method: HttpRequestMethod.GET, url: 'http://example.com' },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const linkElement = screen.getByTitle('view data links and actions');
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
expect(linkElement.tagName).toBe('A');
|
||||
expect(linkElement).toHaveAttribute('aria-haspopup', 'menu');
|
||||
expect(linkElement).toHaveTextContent('Test Link');
|
||||
});
|
||||
});
|
||||
|
||||
describe('no links or actions', () => {
|
||||
it('passes the children through when no links or actions are present', () => {
|
||||
const links = [
|
||||
{ title: 'My link', url: 'http://example.com' },
|
||||
{ title: 'Another link', url: 'http://example.com' },
|
||||
];
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => []),
|
||||
config: {
|
||||
links,
|
||||
actions: [],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const childElement = screen.getByText('Test Link');
|
||||
expect(childElement).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
+9
-5
@@ -1,10 +1,10 @@
|
||||
import { memo, ReactNode } from 'react';
|
||||
|
||||
import { Field } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n';
|
||||
|
||||
import { renderSingleLink } from '../DataLinksActionsTooltip';
|
||||
|
||||
import { getCellLinks } from './utils';
|
||||
import { renderSingleLink } from '../../DataLinksActionsTooltip';
|
||||
import { getCellLinks } from '../utils';
|
||||
|
||||
interface MaybeWrapWithLinkProps {
|
||||
field: Field;
|
||||
@@ -23,8 +23,12 @@ export const MaybeWrapWithLink = memo(({ field, rowIdx, children }: MaybeWrapWit
|
||||
}
|
||||
// as faux link that acts as hit-area for tooltip activation
|
||||
else if (linksCount + actionsCount > 0) {
|
||||
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
||||
return <a aria-haspopup="menu">{children}</a>;
|
||||
return (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
||||
<a title={t('table.link-wrapper.menu', 'view data links and actions')} aria-haspopup="menu">
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
// raw value
|
||||
@@ -12751,6 +12751,9 @@
|
||||
"label-alt-text": "Alt text",
|
||||
"label-title-text": "Title text"
|
||||
},
|
||||
"link-wrapper": {
|
||||
"menu": "view data links and actions"
|
||||
},
|
||||
"markdown-cell-options-editor": {
|
||||
"description-dynamic-height": "We recommend enabling pagination with this option to avoid performance issues.",
|
||||
"label": {
|
||||
|
||||
Reference in New Issue
Block a user