|
|
|
@ -1,6 +1,7 @@ |
|
|
|
|
import { render, screen } from '@testing-library/react'; |
|
|
|
|
import { render, screen, waitFor, findAllByRole } from '@testing-library/react'; |
|
|
|
|
import userEvent from '@testing-library/user-event'; |
|
|
|
|
import React from 'react'; |
|
|
|
|
import { getSelectParent } from 'test/helpers/selectOptionInTest'; |
|
|
|
|
|
|
|
|
|
import { createLokiDatasource } from '../../mocks'; |
|
|
|
|
|
|
|
|
@ -30,6 +31,96 @@ describe('LokiQueryBuilderContainer', () => { |
|
|
|
|
refId: 'A', |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
it('uses | to separate multiple values in label filters', async () => { |
|
|
|
|
const props = { |
|
|
|
|
query: { |
|
|
|
|
expr: '{app="app1"}', |
|
|
|
|
refId: 'A', |
|
|
|
|
}, |
|
|
|
|
datasource: createLokiDatasource(), |
|
|
|
|
onChange: jest.fn(), |
|
|
|
|
onRunQuery: () => {}, |
|
|
|
|
showExplain: false, |
|
|
|
|
}; |
|
|
|
|
props.datasource.getDataSamples = jest.fn().mockResolvedValue([]); |
|
|
|
|
props.datasource.languageProvider.fetchSeriesLabels = jest.fn().mockReturnValue({ job: ['grafana', 'loki'] }); |
|
|
|
|
props.onChange = jest.fn(); |
|
|
|
|
|
|
|
|
|
render(<LokiQueryBuilderContainer {...props} />); |
|
|
|
|
await userEvent.click(screen.getByLabelText('Add')); |
|
|
|
|
const labels = screen.getByText(/Label filters/); |
|
|
|
|
const selects = await findAllByRole(getSelectParent(labels)!, 'combobox'); |
|
|
|
|
await userEvent.click(selects[3]); |
|
|
|
|
userEvent.click(await screen.findByText('job')); |
|
|
|
|
|
|
|
|
|
await userEvent.click(selects[4]); |
|
|
|
|
userEvent.click(await screen.findByText('=~')); |
|
|
|
|
|
|
|
|
|
await userEvent.click(selects[5]); |
|
|
|
|
userEvent.click(await screen.findByText('grafana')); |
|
|
|
|
|
|
|
|
|
await userEvent.click(selects[5]); |
|
|
|
|
userEvent.click(await screen.findByText('loki')); |
|
|
|
|
|
|
|
|
|
await waitFor(() => { |
|
|
|
|
expect(props.onChange).toBeCalledWith({ expr: '{app="app1", job=~"grafana|loki"}', refId: 'A' }); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('highlights the query in preview using loki grammar', async () => { |
|
|
|
|
const props = { |
|
|
|
|
query: { |
|
|
|
|
expr: '{app="baz"} | logfmt', |
|
|
|
|
refId: 'A', |
|
|
|
|
}, |
|
|
|
|
datasource: createLokiDatasource(), |
|
|
|
|
onChange: jest.fn(), |
|
|
|
|
onRunQuery: () => {}, |
|
|
|
|
showExplain: false, |
|
|
|
|
}; |
|
|
|
|
props.datasource.getDataSamples = jest.fn().mockResolvedValue([]); |
|
|
|
|
render(<LokiQueryBuilderContainer {...props} />); |
|
|
|
|
expect(screen.getByText('{')).toHaveClass('token punctuation'); |
|
|
|
|
expect(screen.getByText('"baz"')).toHaveClass('token label-value attr-value'); |
|
|
|
|
expect(screen.getByText('|')).toHaveClass('token pipe-operator operator'); |
|
|
|
|
expect(screen.getByText('logfmt')).toHaveClass('token pipe-operations keyword'); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('shows conflicting label expressions', async () => { |
|
|
|
|
const props = { |
|
|
|
|
query: { |
|
|
|
|
expr: '{job="grafana"} | app!="bar" | app="bar"', |
|
|
|
|
refId: 'A', |
|
|
|
|
}, |
|
|
|
|
datasource: createLokiDatasource(), |
|
|
|
|
onChange: jest.fn(), |
|
|
|
|
onRunQuery: () => {}, |
|
|
|
|
showExplain: false, |
|
|
|
|
}; |
|
|
|
|
props.datasource.getDataSamples = jest.fn().mockResolvedValue([]); |
|
|
|
|
|
|
|
|
|
render(<LokiQueryBuilderContainer {...props} />); |
|
|
|
|
expect(screen.getAllByText('You have conflicting label filters')).toHaveLength(2); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('uses <expr> as placeholder for query in explain section', async () => { |
|
|
|
|
const props = { |
|
|
|
|
query: { |
|
|
|
|
expr: '{job="grafana"} | logfmt', |
|
|
|
|
refId: 'A', |
|
|
|
|
}, |
|
|
|
|
datasource: createLokiDatasource(), |
|
|
|
|
onChange: jest.fn(), |
|
|
|
|
onRunQuery: () => {}, |
|
|
|
|
showExplain: true, |
|
|
|
|
}; |
|
|
|
|
props.datasource.getDataSamples = jest.fn().mockResolvedValue([]); |
|
|
|
|
|
|
|
|
|
render(<LokiQueryBuilderContainer {...props} />); |
|
|
|
|
expect(screen.getByText('<')).toBeInTheDocument(); |
|
|
|
|
expect(screen.getByText('expr')).toBeInTheDocument(); |
|
|
|
|
expect(screen.getByText('>')).toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
async function addOperation(section: string, op: string) { |
|
|
|
|