import ReactEchartsCore from 'echarts-for-react/lib/core';
import {initializeOrg} from 'sentry-test/initializeOrg';
import {addMetricsDataMock} from 'sentry-test/performance/addMetricsDataMock';
import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
import {Organization} from 'sentry/types/organization';
import {Project} from 'sentry/types/project';
import EventView from 'sentry/utils/discover/eventView';
import {MetricsCardinalityProvider} from 'sentry/utils/performance/contexts/metricsCardinality';
import {MetricsBaselineContainer} from './metricsBaselineContainer';
jest.mock('echarts-for-react/lib/core', () => {
return jest.fn(({style}) => {
return
echarts mock
;
});
});
export function renderMetricsBaselineContainer(
organization: Organization,
project: Project,
eventView: EventView,
yAxis: string[]
) {
const routerLocation: {query: {project?: number}} = {
query: {project: parseInt(project.id, 10)},
};
const router = {
location: routerLocation,
};
const initialData = initializeOrg({
organization,
projects: [project],
project,
router,
});
const location = initialData.router.location;
const api = new MockApiClient();
render(
undefined}
onDisplayChange={() => undefined}
onTopEventsChange={() => undefined}
onIntervalChange={() => undefined}
eventView={eventView}
api={api}
confirmedQuery
location={location}
router={initialData.router}
yAxis={yAxis}
/>
);
return initialData.router;
}
describe('MetricsBaselineContainer', function () {
const features = ['discover-basic'];
const project = TestStubs.Project();
const eventView = EventView.fromSavedQuery({
id: '',
name: 'test query',
version: 2,
fields: ['transaction', 'p50(transaction.duration)'],
projects: [project.id],
});
let eventsStatsMock: jest.Mock | undefined;
let eventsMock: jest.Mock | undefined;
beforeEach(function () {
(ReactEchartsCore as jest.Mock).mockClear();
eventsStatsMock = MockApiClient.addMockResponse({
url: '/organizations/org-slug/events-stats/',
body: {
data: [
[1663272000, [{count: 2066}]],
[1663272300, [{count: 2158}]],
],
},
});
eventsMock = MockApiClient.addMockResponse({
method: 'GET',
url: `/organizations/org-slug/events/`,
body: {
data: [{}],
meta: {},
},
});
MockApiClient.addMockResponse({
url: '/organizations/org-slug/releases/stats/',
body: [],
});
});
afterEach(() => {
jest.clearAllMocks();
});
it('enables processed baseline toggle if metrics cardinality conditions met', async function () {
addMetricsDataMock();
eventsMock = MockApiClient.addMockResponse({
method: 'GET',
url: `/organizations/org-slug/events/`,
body: {
data: [{'count()': 19266771}],
meta: {},
},
});
const organization = TestStubs.Organization({
features: [
...features,
'discover-metrics-baseline',
'server-side-sampling',
'mep-rollout-flag',
],
});
const yAxis = ['p50(transaction.duration)'];
renderMetricsBaselineContainer(organization, project, eventView, yAxis);
await waitFor(() => {
expect(eventsStatsMock).toHaveBeenCalledWith(
'/organizations/org-slug/events-stats/',
expect.objectContaining({
query: expect.objectContaining({
dataset: 'metrics',
}),
})
);
});
expect(eventsMock).toHaveBeenCalledWith(
'/organizations/org-slug/events/',
expect.objectContaining({
query: expect.objectContaining({
dataset: 'metrics',
}),
})
);
expect(screen.getByText(/Processed events/i)).toBeInTheDocument();
expect(screen.getByText(/19m/i)).toBeInTheDocument();
expect(screen.getByTestId('processed-events-toggle')).toBeEnabled();
});
it('displays metrics baseline', async function () {
addMetricsDataMock();
const organization = TestStubs.Organization({
features: [
...features,
'discover-metrics-baseline',
'server-side-sampling',
'mep-rollout-flag',
],
});
const yAxis = ['p50(transaction.duration)'];
renderMetricsBaselineContainer(organization, project, eventView, yAxis);
await waitFor(() => {
expect(eventsStatsMock).toHaveBeenCalledWith(
'/organizations/org-slug/events-stats/',
expect.objectContaining({
query: expect.objectContaining({
dataset: 'metrics',
}),
})
);
});
expect(screen.getByText(/Processed events/i)).toBeInTheDocument();
expect(screen.getByTestId('processed-events-toggle')).toBeEnabled();
await waitFor(() => {
expect(ReactEchartsCore).toHaveBeenLastCalledWith(
expect.objectContaining({
option: expect.objectContaining({
legend: expect.objectContaining({
data: expect.arrayContaining([
'processed events: p50(transaction.duration)',
]),
}),
}),
}),
{}
);
});
});
it('disables processed baseline toggle if metrics cardinality conditions not met', function () {
const organization = TestStubs.Organization({
features: [...features, 'discover-metrics-baseline'],
});
const yAxis = ['p50(transaction.duration)'];
renderMetricsBaselineContainer(organization, project, eventView, yAxis);
expect(screen.getByText(/Processed events/i)).toBeInTheDocument();
expect(screen.getByTestId('processed-events-toggle')).toBeDisabled();
});
it('disables toggle if discover hits the events dataset', function () {
addMetricsDataMock();
const organization = TestStubs.Organization({
features: [
...features,
'discover-metrics-baseline',
'server-side-sampling',
'mep-rollout-flag',
],
});
const yAxis = ['count()'];
renderMetricsBaselineContainer(organization, project, eventView, yAxis);
expect(screen.getByText(/Processed events/i)).toBeInTheDocument();
expect(screen.getByTestId('processed-events-toggle')).toBeDisabled();
});
it('pushes toggle selection to URL', async function () {
addMetricsDataMock();
const organization = TestStubs.Organization({
features: [
...features,
'discover-metrics-baseline',
'server-side-sampling',
'mep-rollout-flag',
],
});
const yAxis = ['p50(transaction.duration)'];
const router = renderMetricsBaselineContainer(
organization,
project,
eventView,
yAxis
);
await waitFor(() => {
expect(eventsStatsMock).toHaveBeenCalledWith(
'/organizations/org-slug/events-stats/',
expect.objectContaining({
query: expect.objectContaining({
dataset: 'metrics',
}),
})
);
});
expect(screen.getByTestId('processed-events-toggle')).toBeEnabled();
expect(screen.getByTestId('processed-events-toggle')).toBeChecked();
userEvent.click(screen.getByTestId('processed-events-toggle'));
expect(router.push).toHaveBeenCalledWith(
expect.objectContaining({query: expect.objectContaining({baseline: '0'})})
);
});
});