import {TagsFixture} from 'sentry-fixture/tags'; import {initializeOrg} from 'sentry-test/initializeOrg'; import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary'; import ProjectsStore from 'sentry/stores/projectsStore'; import type {Organization} from 'sentry/types/organization'; import {DashboardWidgetSource} from 'sentry/views/dashboards/types'; import WidgetBuilder from 'sentry/views/dashboards/widgetBuilder'; jest.unmock('lodash/debounce'); function mockRequests(orgSlug: Organization['slug']) { const eventsMock = MockApiClient.addMockResponse({ url: `/organizations/${orgSlug}/events/`, method: 'GET', statusCode: 200, body: { meta: {}, data: [], }, }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/tags/', method: 'GET', body: TagsFixture(), }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/users/', body: [], }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/projects/', method: 'GET', body: [], }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/measurements-meta/', method: 'GET', body: {'measurements.custom.measurement': {functions: ['p99']}}, }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/metrics-compatibility/', method: 'GET', body: { incompatible_projects: [], compatible_projects: [1], }, }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/metrics-compatibility-sums/', method: 'GET', body: { sum: { metrics: 988803, metrics_null: 0, metrics_unparam: 132, }, }, }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/releases/', body: [], }); return {eventsMock}; } describe('VisualizationStep', function () { const {organization, projects, router} = initializeOrg({ organization: { features: ['dashboards-edit', 'global-views', 'dashboards-mep'], }, router: { location: { query: { source: DashboardWidgetSource.DASHBOARDS, }, }, }, }); beforeEach(function () { ProjectsStore.loadInitialData(projects); }); it('debounce works as expected and requests are not triggered often', async function () { const {eventsMock} = mockRequests(organization.slug); render( , { router, organization, } ); await waitFor(() => expect(eventsMock).toHaveBeenCalledTimes(1)); await userEvent.type(await screen.findByPlaceholderText('Alias'), 'abc', { delay: null, }); await waitFor(() => expect(eventsMock).toHaveBeenCalledTimes(1)); }); it('displays stored data alert', async function () { mockRequests(organization.slug); MockApiClient.addMockResponse({ url: `/organizations/${organization.slug}/events/`, method: 'GET', statusCode: 200, body: { meta: {isMetricsData: false}, data: [], }, }); render( , { router, organization: { ...organization, features: [...organization.features, 'dynamic-sampling', 'mep-rollout-flag'], }, } ); await screen.findByText(/we've automatically adjusted your results/i); }); it('uses release from URL params when querying', async function () { const {eventsMock} = mockRequests(organization.slug); render( , { router, organization, } ); await waitFor(() => expect(eventsMock).toHaveBeenCalledWith( '/organizations/org-slug/events/', expect.objectContaining({ query: expect.objectContaining({query: ' release:"v1" '}), }) ) ); }); it('does not trigger an extra events request when adding a column', async function () { const {eventsMock} = mockRequests(organization.slug); render( , { router, organization, } ); await userEvent.click(screen.getByText('Add a Column')); // Only called once on the initial render await waitFor(() => expect(eventsMock).toHaveBeenCalledTimes(1)); }); });