import {waitFor} from 'sentry-test/reactTestingLibrary'; import { doMetricsRequest, fetchMetricsFields, fetchMetricsTags, } from 'sentry/actionCreators/metrics'; import MetricsMetaActions from 'sentry/actions/metricsMetaActions'; import MetricsTagActions from 'sentry/actions/metricTagActions'; import {Client} from 'sentry/api'; import MetricsMetaStore from 'sentry/stores/metricsMetaStore'; import MetricsTagStore from 'sentry/stores/metricsTagStore'; import {SessionMetric} from 'sentry/utils/metrics/fields'; describe('Metrics ActionCreator', function () { const api = new Client(); const orgSlug = TestStubs.Organization().slug; describe('doMetricsRequest', function () { const options = { field: [SessionMetric.SESSION], orgSlug, cursor: undefined, environment: [], groupBy: ['session.status'], interval: '1h', limit: 5, orderBy: SessionMetric.SESSION, project: [TestStubs.Project().id], query: 'release:123', statsPeriod: '14d', }; let mock; beforeEach(function () { MockApiClient.clearMockResponses(); mock = MockApiClient.addMockResponse({ url: `/organizations/${orgSlug}/metrics/data/`, body: { data: [], }, }); }); it('requests metrics data', function () { doMetricsRequest(api, options); expect(mock).toHaveBeenCalledTimes(1); expect(mock).toHaveBeenLastCalledWith( `/organizations/${orgSlug}/metrics/data/`, expect.objectContaining({ query: { environment: [], field: ['sentry.sessions.session'], groupBy: ['session.status'], interval: '1h', orderBy: 'sentry.sessions.session', per_page: 5, project: ['2'], query: 'release:123', statsPeriod: '14d', }, }) ); }); it('fills in interval based on start and end', function () { doMetricsRequest(api, { ...options, statsPeriod: undefined, interval: undefined, start: '2022-01-01T00:00:00', end: '2022-03-01T00:00:00', }); expect(mock).toHaveBeenCalledTimes(1); expect(mock).toHaveBeenLastCalledWith( `/organizations/${orgSlug}/metrics/data/`, expect.objectContaining({ query: { environment: [], field: ['sentry.sessions.session'], groupBy: ['session.status'], interval: '4h', orderBy: 'sentry.sessions.session', per_page: 5, project: ['2'], query: 'release:123', start: '2022-01-01T00:00:00.000', end: '2022-03-01T00:00:00.000', }, }) ); }); it('ignores falsy fields and groupBys', function () { doMetricsRequest(api, { ...options, field: [SessionMetric.SESSION, ''], groupBy: ['session.status', ''], }); expect(mock).toHaveBeenCalledTimes(1); expect(mock).toHaveBeenLastCalledWith( `/organizations/${orgSlug}/metrics/data/`, expect.objectContaining({ query: expect.objectContaining({ field: ['sentry.sessions.session'], groupBy: ['session.status'], }), }) ); }); }); describe('fetchMetricsTags', function () { let mock; const tags = [{key: 'release'}, {key: 'environment'}]; beforeEach(function () { MockApiClient.clearMockResponses(); mock = MockApiClient.addMockResponse({ url: `/organizations/${orgSlug}/metrics/tags/`, body: tags, }); jest.restoreAllMocks(); jest.spyOn(MetricsTagActions, 'loadMetricsTagsSuccess'); jest.spyOn(MetricsTagStore, 'reset'); }); it('fetches api and updates store', async function () { fetchMetricsTags(api, orgSlug, [1], [`sum(${SessionMetric.SESSION})`]); await waitFor(() => expect(MetricsTagStore.reset).toHaveBeenCalledTimes(1)); expect(mock).toHaveBeenCalledTimes(1); expect(mock).toHaveBeenLastCalledWith( `/organizations/${orgSlug}/metrics/tags/`, expect.objectContaining({ query: {metric: ['sum(sentry.sessions.session)'], project: [1]}, }) ); expect(MetricsTagActions.loadMetricsTagsSuccess).toHaveBeenCalledTimes(1); expect(MetricsTagActions.loadMetricsTagsSuccess).toHaveBeenCalledWith(tags); }); }); describe('fetchMetricsFields', function () { let mock; const meta = [ {name: 'sentry.sessions.session', type: 'counter', operations: ['sum'], unit: null}, { name: 'sentry.sessions.user', type: 'set', operations: ['count_unique'], unit: null, }, ]; beforeEach(function () { MockApiClient.clearMockResponses(); mock = MockApiClient.addMockResponse({ url: `/organizations/${orgSlug}/metrics/meta/`, body: meta, }); jest.restoreAllMocks(); jest.spyOn(MetricsMetaActions, 'loadMetricsMetaSuccess'); jest.spyOn(MetricsMetaStore, 'reset'); }); it('fetches api and updates store', async function () { fetchMetricsFields(api, orgSlug, [1]); await waitFor(() => expect(MetricsMetaStore.reset).toHaveBeenCalledTimes(1)); expect(mock).toHaveBeenCalledTimes(1); expect(mock).toHaveBeenLastCalledWith( `/organizations/${orgSlug}/metrics/meta/`, expect.objectContaining({ query: {project: [1]}, }) ); expect(MetricsMetaActions.loadMetricsMetaSuccess).toHaveBeenCalledTimes(1); expect(MetricsMetaActions.loadMetricsMetaSuccess).toHaveBeenCalledWith(meta); }); }); });