123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910 |
- import styled from '@emotion/styled';
- import {initializeOrg} from 'sentry-test/initializeOrg';
- import {
- fireEvent,
- render,
- screen,
- userEvent,
- waitFor,
- within,
- } from 'sentry-test/reactTestingLibrary';
- import {makeCloseButton} from 'sentry/components/globalModal/components';
- import TagStore from 'sentry/stores/tagStore';
- import type {QueryFieldValue} from 'sentry/utils/discover/fields';
- import ColumnEditModal from 'sentry/views/discover/table/columnEditModal';
- const stubEl = styled(p => p.children);
- function mountModal({columns, onApply, customMeasurements}, initialData) {
- return render(
- <ColumnEditModal
- CloseButton={makeCloseButton(() => {})}
- Header={c => <div>{c.children}</div>}
- Footer={stubEl()}
- Body={stubEl()}
- organization={initialData.organization}
- columns={columns}
- onApply={onApply}
- closeModal={jest.fn()}
- measurementKeys={null}
- customMeasurements={customMeasurements}
- />,
- {context: initialData.routerContext}
- );
- }
- // Get all queryField components which represent a row in the column editor.
- const findAllQueryFields = () => screen.findAllByTestId('queryField');
- // Get the nth label (value) within the row of the column editor.
- const findAllQueryFieldNthCell = async nth =>
- (await findAllQueryFields())
- .map(f => within(f).getAllByTestId('label')[nth])
- .filter(Boolean);
- const getAllQueryFields = () => screen.getAllByTestId('queryField');
- const getAllQueryFieldsNthCell = nth =>
- getAllQueryFields()
- .map(f => within(f).getAllByTestId('label')[nth])
- .filter(Boolean);
- const openMenu = async (row, column = 0) => {
- const queryFields = await screen.findAllByTestId('queryField');
- const queryField = queryFields[row];
- expect(queryField).toBeInTheDocument();
- const labels = within(queryField).queryAllByTestId('label');
- if (labels.length > 0) {
- await userEvent.click(labels[column]);
- } else {
- // For test adding a new column, no existing label.
- await userEvent.click(screen.getByText('(Required)'));
- }
- };
- const selectByLabel = async (label, options) => {
- await openMenu(options.at);
- const menuOptions = screen.getAllByTestId('menu-list-item-label'); // TODO: Can likely switch to menuitem role and match against label
- const opt = menuOptions.find(e => e.textContent?.includes(label));
- await userEvent.click(opt!);
- };
- describe('Discover -> ColumnEditModal', function () {
- beforeEach(() => {
- TagStore.reset();
- TagStore.loadTagsSuccess([
- {name: 'browser.name', key: 'browser.name'},
- {name: 'custom-field', key: 'custom-field'},
- {name: 'user', key: 'user'},
- ]);
- });
- const initialData = initializeOrg({
- organization: {
- features: ['performance-view', 'dashboards-mep'],
- },
- });
- const columns: QueryFieldValue[] = [
- {
- kind: 'field',
- field: 'event.type',
- },
- {
- kind: 'field',
- field: 'browser.name',
- },
- {
- kind: 'function',
- function: ['count', 'id', '', ''],
- },
- {
- kind: 'function',
- function: ['count_unique', 'title', '', ''],
- },
- {
- kind: 'function',
- function: ['p95', '', '', ''],
- },
- {
- kind: 'field',
- field: 'issue.id',
- },
- {
- kind: 'function',
- function: ['count_unique', 'issue.id', '', ''],
- },
- ];
- describe('basic rendering', function () {
- it('renders fields and basic controls, async delete and grab buttons', async function () {
- mountModal(
- {
- columns,
- onApply: jest.fn(),
- customMeasurements: {},
- },
- initialData
- );
- // Should have fields equal to the columns.
- expect((await findAllQueryFieldNthCell(0)).map(el => el.textContent)).toEqual([
- 'event.type',
- 'browser.name',
- 'count()',
- 'count_unique(…)',
- 'p95(…)',
- 'issue.id',
- 'count_unique(…)', // extra because of the function
- ]);
- expect(screen.getByRole('button', {name: 'Apply'})).toBeInTheDocument();
- expect(screen.getByRole('button', {name: 'Add a Column'})).toBeInTheDocument();
- expect(screen.getAllByRole('button', {name: 'Remove column'})).toHaveLength(
- columns.length
- );
- expect(screen.getAllByRole('button', {name: 'Drag to reorder'})).toHaveLength(
- columns.length
- );
- });
- });
- describe('rendering unknown fields', function () {
- it('renders unknown fields in field and field parameter controls', async function () {
- mountModal(
- {
- columns: [
- {kind: 'function', function: ['count_unique', 'user-defined']},
- {kind: 'field', field: 'user-def'},
- ],
- onApply: jest.fn(),
- customMeasurements: {},
- },
- initialData
- );
- expect((await findAllQueryFieldNthCell(0)).map(el => el.textContent)).toEqual([
- 'count_unique(…)',
- 'user-def',
- ]);
- expect(getAllQueryFieldsNthCell(1).map(el => el.textContent)).toEqual([
- 'user-defined',
- ]);
- });
- });
- describe('rendering tags that overlap fields & functions', function () {
- beforeEach(() => {
- TagStore.reset();
- TagStore.loadTagsSuccess([
- {name: 'project', key: 'project'},
- {name: 'count', key: 'count'},
- ]);
- });
- it('selects tag expressions that overlap fields', async function () {
- mountModal(
- {
- columns: [
- {kind: 'field', field: 'tags[project]'},
- {kind: 'field', field: 'tags[count]'},
- ],
- onApply: jest.fn(),
- customMeasurements: {},
- },
- initialData
- );
- expect((await findAllQueryFieldNthCell(0)).map(el => el.textContent)).toEqual([
- 'project',
- 'count',
- ]);
- });
- it('selects tag expressions that overlap functions', async function () {
- mountModal(
- {
- columns: [
- {kind: 'field', field: 'tags[project]'},
- {kind: 'field', field: 'tags[count]'},
- ],
- onApply: jest.fn(),
- customMeasurements: {},
- },
- initialData
- );
- expect((await findAllQueryFieldNthCell(0)).map(el => el.textContent)).toEqual([
- 'project',
- 'count',
- ]);
- });
- });
- describe('rendering functions', function () {
- it('renders three columns when needed', async function () {
- mountModal(
- {
- columns: [
- {kind: 'function', function: ['count', 'id']},
- {kind: 'function', function: ['count_unique', 'title']},
- {kind: 'function', function: ['percentile', 'transaction.duration', '0.66']},
- ],
- onApply: jest.fn(),
- customMeasurements: {},
- },
- initialData
- );
- const queryFields = await findAllQueryFields();
- const countRow = queryFields[0];
- expect(
- within(countRow)
- .getAllByTestId('label')
- .map(el => el.textContent)
- ).toEqual(['count()']);
- const percentileRow = queryFields[2];
- expect(
- within(percentileRow)
- .getAllByTestId('label')
- .map(el => el.textContent)
- ).toEqual(['percentile(…)', 'transaction.duration']);
- expect(within(percentileRow).getByDisplayValue('0.66')).toBeInTheDocument();
- });
- });
- describe('function & column selection', function () {
- let onApply;
- beforeEach(function () {
- onApply = jest.fn();
- });
- it('restricts column choices', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- await selectByLabel('avg(…)', {
- at: 0,
- });
- await openMenu(0, 1);
- const menuOptions = await screen.findAllByTestId('menu-list-item-label');
- const menuOptionsText = menuOptions.map(el => el.textContent);
- expect(menuOptionsText).toContain('transaction.duration');
- expect(menuOptionsText).not.toContain('title');
- });
- it('shows no options for parameterless functions', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- await selectByLabel('last_seen()', {name: 'field', at: 0, control: true});
- expect(screen.getByTestId('blankSpace')).toBeInTheDocument();
- });
- it('shows additional inputs for multi-parameter functions', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- await selectByLabel('percentile(\u2026)', {
- name: 'field',
- at: 0,
- });
- expect(screen.getAllByTestId('label')[0]).toHaveTextContent('percentile(…)');
- expect(
- within(screen.getByTestId('queryField')).getByDisplayValue(0.5)
- ).toBeInTheDocument();
- });
- it('handles scalar field parameters', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- await selectByLabel('apdex(\u2026)', {
- name: 'field',
- at: 0,
- });
- expect(screen.getAllByRole('textbox')[1]).toHaveValue('300');
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- await waitFor(() => {
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['apdex', '300', undefined, undefined]},
- ]);
- });
- });
- it('handles parameter overrides', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- await selectByLabel('apdex(…)', {
- name: 'field',
- at: 0,
- });
- expect(screen.getAllByRole('textbox')[1]).toHaveValue('300');
- });
- it('clears unused parameters', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- // Choose percentile, then apdex which has fewer parameters and different types.
- await selectByLabel('percentile(\u2026)', {
- name: 'field',
- at: 0,
- });
- await selectByLabel('apdex(\u2026)', {
- name: 'field',
- at: 0,
- });
- // Apply the changes so we can see the new columns.
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['apdex', '300', undefined, undefined]},
- ]);
- });
- it('clears all unused parameters', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- // Choose percentile, then failure_rate which has no parameters.
- await selectByLabel('percentile(\u2026)', {
- name: 'field',
- at: 0,
- });
- await selectByLabel('failure_rate()', {
- name: 'field',
- at: 0,
- });
- // Apply the changes so we can see the new columns.
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['failure_rate', '', undefined, undefined]},
- ]);
- });
- it('clears all unused parameters with count_if to two parameter function', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- // Choose percentile, then failure_rate which has no parameters.
- await selectByLabel('count_if(\u2026)', {
- name: 'field',
- at: 0,
- });
- await selectByLabel('user', {name: 'parameter', at: 0});
- await selectByLabel('count_miserable(\u2026)', {
- name: 'field',
- at: 0,
- });
- // Apply the changes so we can see the new columns.
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['count_miserable', 'user', '300', undefined]},
- ]);
- });
- it('clears all unused parameters with count_if to one parameter function', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- // Choose percentile, then failure_rate which has no parameters.
- await selectByLabel('count_if(\u2026)', {
- name: 'field',
- at: 0,
- });
- await selectByLabel('user', {name: 'parameter', at: 0});
- await selectByLabel('count_unique(\u2026)', {
- name: 'field',
- at: 0,
- });
- // Apply the changes so we can see the new columns.
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['count_unique', '300', undefined, undefined]},
- ]);
- });
- it('clears all unused parameters with count_if to parameterless function', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- // Choose percentile, then failure_rate which has no parameters.
- await selectByLabel('count_if(\u2026)', {
- name: 'field',
- at: 0,
- });
- await selectByLabel('count()', {
- name: 'field',
- at: 0,
- });
- // Apply the changes so we can see the new columns.
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['count', '', undefined, undefined]},
- ]);
- });
- it('updates equation errors when they change', async function () {
- mountModal(
- {
- columns: [
- {
- kind: 'equation',
- field: '1 / 0',
- },
- ],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- await userEvent.hover(await screen.findByTestId('arithmeticErrorWarning'));
- expect(await screen.findByText('Division by 0 is not allowed')).toBeInTheDocument();
- const input = screen.getAllByRole('textbox')[0];
- expect(input).toHaveValue('1 / 0');
- await userEvent.clear(input);
- await userEvent.type(input, '1+1+1+1+1+1+1+1+1+1+1+1');
- await userEvent.click(document.body);
- await waitFor(() => expect(input).toHaveValue('1+1+1+1+1+1+1+1+1+1+1+1'));
- await userEvent.hover(screen.getByTestId('arithmeticErrorWarning'));
- expect(await screen.findByText('Maximum operators exceeded')).toBeInTheDocument();
- });
- it('resets required field to previous value if cleared', async function () {
- const initialColumnVal = '0.6';
- mountModal(
- {
- columns: [
- {
- kind: 'function',
- function: [
- 'percentile',
- 'transaction.duration',
- initialColumnVal,
- undefined,
- ],
- },
- ],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- const input = screen.getAllByRole('textbox')[2]; // The numeric input
- expect(input).toHaveValue(initialColumnVal);
- await userEvent.clear(input);
- await userEvent.click(document.body); // Unfocusing the input should revert it to the previous value
- expect(input).toHaveValue(initialColumnVal);
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- expect(onApply).toHaveBeenCalledWith([
- {
- kind: 'function',
- function: ['percentile', 'transaction.duration', initialColumnVal, undefined],
- },
- ]);
- });
- });
- describe('equation automatic update', function () {
- let onApply;
- beforeEach(function () {
- onApply = jest.fn();
- });
- it('update simple equation columns when they change', async function () {
- mountModal(
- {
- columns: [
- {
- kind: 'function',
- function: ['count_unique', 'user'],
- },
- {
- kind: 'function',
- function: ['p95', ''],
- },
- {
- kind: 'equation',
- field: '(p95() / count_unique(user) ) * 100',
- },
- ],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- await selectByLabel('count_if(\u2026)', {
- name: 'field',
- at: 0,
- });
- // Apply the changes so we can see the new columns.
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['count_if', 'user', 'equals', '300']},
- {kind: 'function', function: ['p95', '']},
- {kind: 'equation', field: '(p95() / count_if(user,equals,300) ) * 100'},
- ]);
- });
- it('update equation with repeated columns when they change', async function () {
- mountModal(
- {
- columns: [
- {
- kind: 'function',
- function: ['count_unique', 'user'],
- },
- {
- kind: 'equation',
- field:
- 'count_unique(user) + (count_unique(user) - count_unique(user)) * 5',
- },
- ],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- await selectByLabel('count()', {
- name: 'field',
- at: 0,
- });
- // Apply the changes so we can see the new columns.
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['count', '', undefined, undefined]},
- {kind: 'equation', field: 'count() + (count() - count()) * 5'},
- ]);
- });
- it('handles equations with duplicate fields', async function () {
- mountModal(
- {
- columns: [
- {
- kind: 'field',
- field: 'spans.db',
- },
- {
- kind: 'field',
- field: 'spans.db',
- },
- {
- kind: 'equation',
- field: 'spans.db - spans.db',
- },
- ],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- await selectByLabel('count()', {
- name: 'field',
- at: 0,
- });
- // Apply the changes so we can see the new columns.
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- // Because spans.db is still a selected column it isn't swapped
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['count', '', undefined, undefined]},
- {kind: 'field', field: 'spans.db'},
- {kind: 'equation', field: 'spans.db - spans.db'},
- ]);
- });
- it('handles equations with duplicate functions', async function () {
- mountModal(
- {
- columns: [
- {
- kind: 'function',
- function: ['count', '', undefined, undefined],
- },
- {
- kind: 'function',
- function: ['count', '', undefined, undefined],
- },
- {
- kind: 'equation',
- field: 'count() - count()',
- },
- ],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- await selectByLabel('count_unique(\u2026)', {
- name: 'field',
- at: 0,
- });
- // Apply the changes so we can see the new columns.
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['count_unique', 'user', undefined, undefined]},
- {kind: 'function', function: ['count', '', undefined, undefined]},
- {kind: 'equation', field: 'count() - count()'},
- ]);
- });
- it('handles incomplete equations', async function () {
- mountModal(
- {
- columns: [
- {
- kind: 'function',
- function: ['count', '', undefined, undefined],
- },
- {
- kind: 'equation',
- field: 'count() - count() arst count() ',
- },
- ],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- expect(await screen.findByTestId('arithmeticErrorWarning')).toBeInTheDocument();
- await selectByLabel('count_unique(\u2026)', {
- name: 'field',
- at: 0,
- });
- // Apply the changes so we can see the new columns.
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- // With the way the parser works only tokens up to the error will be updated
- expect(onApply).toHaveBeenCalledWith([
- {kind: 'function', function: ['count_unique', 'user', undefined, undefined]},
- {
- kind: 'equation',
- field: 'count_unique(user) - count_unique(user) arst count() ',
- },
- ]);
- });
- });
- describe('adding rows', function () {
- it('allows rows to be added, async but only up to 20', async function () {
- mountModal(
- {
- columns: [columns[0]],
- onApply: jest.fn(),
- customMeasurements: {},
- },
- initialData
- );
- expect(await screen.findByTestId('queryField')).toBeInTheDocument();
- const addColumnButton = screen.getByRole('button', {name: 'Add a Column'});
- for (let i = 2; i <= 20; i++) {
- fireEvent.click(addColumnButton);
- expect(await screen.findAllByTestId('queryField')).toHaveLength(i);
- }
- expect(screen.getByRole('button', {name: 'Add a Column'})).toBeDisabled();
- });
- });
- describe('removing rows', function () {
- it('allows rows to be removed, async but not the last one', async function () {
- mountModal(
- {
- columns: [columns[0], columns[1]],
- onApply: jest.fn(),
- customMeasurements: {},
- },
- initialData
- );
- expect(await screen.findAllByTestId('queryField')).toHaveLength(2);
- await userEvent.click(screen.getByTestId('remove-column-0'));
- expect(await screen.findByTestId('queryField')).toBeInTheDocument();
- expect(
- screen.queryByRole('button', {name: 'Remove column'})
- ).not.toBeInTheDocument();
- expect(
- screen.queryByRole('button', {name: 'Drag to reorder'})
- ).not.toBeInTheDocument();
- });
- it('does not count equations towards the count of rows', async function () {
- mountModal(
- {
- columns: [
- columns[0],
- columns[1],
- {
- kind: 'equation',
- field: '5 + 5',
- },
- ],
- onApply: jest.fn(),
- customMeasurements: {},
- },
- initialData
- );
- expect(await screen.findAllByTestId('queryField')).toHaveLength(3);
- await userEvent.click(screen.getByTestId('remove-column-0'));
- expect(await screen.findAllByTestId('queryField')).toHaveLength(2);
- expect(screen.queryByRole('button', {name: 'Remove column'})).toBeInTheDocument();
- expect(screen.queryAllByRole('button', {name: 'Drag to reorder'})).toHaveLength(2);
- });
- it('handles equations being deleted', async function () {
- mountModal(
- {
- columns: [
- {
- kind: 'equation',
- field: '1 / 0',
- },
- columns[0],
- columns[1],
- ],
- onApply: jest.fn(),
- customMeasurements: {},
- },
- initialData
- );
- expect(await screen.findAllByTestId('queryField')).toHaveLength(3);
- expect(screen.getByTestId('arithmeticErrorWarning')).toBeInTheDocument();
- await userEvent.click(screen.getByTestId('remove-column-0'));
- expect(await screen.findAllByTestId('queryField')).toHaveLength(2);
- expect(screen.queryByTestId('arithmeticErrorWarning')).not.toBeInTheDocument();
- });
- });
- describe('apply action', function () {
- const onApply = jest.fn();
- it('reflects added and removed columns', async function () {
- mountModal(
- {
- columns: [columns[0], columns[1]],
- onApply,
- customMeasurements: {},
- },
- initialData
- );
- expect(await screen.findAllByTestId('queryField')).toHaveLength(2);
- // Remove a column, then add a blank one an select a value in it.
- await userEvent.click(screen.getByTestId('remove-column-0'));
- await userEvent.click(screen.getByRole('button', {name: 'Add a Column'}));
- expect(await screen.findAllByTestId('queryField')).toHaveLength(2);
- await selectByLabel('title', {name: 'field', at: 1});
- await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
- expect(onApply).toHaveBeenCalledWith([columns[1], {kind: 'field', field: 'title'}]);
- });
- });
- describe('custom performance metrics', function () {
- it('allows selecting custom performance metrics in dropdown', async function () {
- render(
- <ColumnEditModal
- CloseButton={makeCloseButton(() => {})}
- Header={c => <div>{c.children}</div>}
- Footer={stubEl()}
- Body={stubEl()}
- organization={initialData.organization}
- columns={[columns[0]]}
- onApply={() => undefined}
- closeModal={() => undefined}
- measurementKeys={[]}
- customMeasurements={{
- 'measurements.custom.kibibyte': {
- fieldType: 'number',
- unit: 'KiB',
- key: 'measurements.custom.kibibyte',
- name: 'measurements.custom.kibibyte',
- functions: ['p99'],
- },
- 'measurements.custom.minute': {
- fieldType: 'number',
- key: 'measurements.custom.minute',
- name: 'measurements.custom.minute',
- unit: 'minute',
- functions: ['p99'],
- },
- 'measurements.custom.ratio': {
- fieldType: 'number',
- key: 'measurements.custom.ratio',
- name: 'measurements.custom.ratio',
- unit: 'ratio',
- functions: ['p99'],
- },
- }}
- />
- );
- expect(screen.getByText('event.type')).toBeInTheDocument();
- await userEvent.click(screen.getByText('event.type'));
- await userEvent.type(screen.getAllByText('event.type')[0], 'custom');
- expect(screen.getByText('measurements.custom.kibibyte')).toBeInTheDocument();
- });
- });
- });
|