123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- import {enforceActOnUseLegacyStoreHook, mountWithTheme} from 'sentry-test/enzyme';
- import {initializeOrg} from 'sentry-test/initializeOrg';
- import {act} from 'sentry-test/reactTestingLibrary';
- import {t} from 'sentry/locale';
- import ProjectsStore from 'sentry/stores/projectsStore';
- import {Organization} from 'sentry/types';
- import {WebVital} from 'sentry/utils/fields';
- import {OrganizationContext} from 'sentry/views/organizationContext';
- import TransactionEvents from 'sentry/views/performance/transactionSummary/transactionEvents';
- type Data = {
- features?: string[];
- query?: {
- webVital?: WebVital;
- };
- };
- function initializeData({features: additionalFeatures = [], query = {}}: Data = {}) {
- const features = ['discover-basic', 'performance-view', ...additionalFeatures];
- const organization = TestStubs.Organization({
- features,
- projects: [TestStubs.Project()],
- apdexThreshold: 400,
- });
- const initialData = initializeOrg({
- organization,
- router: {
- location: {
- query: {
- transaction: '/performance',
- project: '1',
- transactionCursor: '1:0:0',
- ...query,
- },
- },
- },
- project: 1,
- projects: [],
- });
- act(() => ProjectsStore.loadInitialData(initialData.organization.projects));
- return initialData;
- }
- const WrappedComponent = ({
- organization,
- ...props
- }: Omit<React.ComponentProps<typeof TransactionEvents>, 'organization'> & {
- organization: Organization;
- }) => {
- return (
- <OrganizationContext.Provider value={organization}>
- <TransactionEvents organization={organization} {...props} />
- </OrganizationContext.Provider>
- );
- };
- describe('Performance > TransactionSummary', function () {
- enforceActOnUseLegacyStoreHook();
- beforeEach(function () {
- // @ts-ignore no-console
- // eslint-disable-next-line no-console
- jest.spyOn(console, 'error').mockImplementation(jest.fn());
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/projects/',
- body: [],
- });
- MockApiClient.addMockResponse({
- url: '/prompts-activity/',
- body: {},
- });
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/sdk-updates/',
- body: [],
- });
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/events/',
- body: {
- data: [
- {
- 'p100()': 9502,
- 'p99()': 9285.7,
- 'p95()': 7273.6,
- 'p75()': 3639.5,
- 'p50()': 755.5,
- },
- ],
- meta: {
- fields: {
- 'p100()': 'duration',
- 'p99()': 'duration',
- 'p95()': 'duration',
- 'p75()': 'duration',
- 'p50()': 'duration',
- },
- },
- },
- match: [
- (_, options) => {
- return options.query?.field?.includes('p95()');
- },
- ],
- });
- // Transaction list response
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/events/',
- headers: {
- Link:
- '<http://localhost/api/0/organizations/org-slug/events/?cursor=2:0:0>; rel="next"; results="true"; cursor="2:0:0",' +
- '<http://localhost/api/0/organizations/org-slug/events/?cursor=1:0:0>; rel="previous"; results="false"; cursor="1:0:0"',
- },
- body: {
- meta: {
- fields: {
- id: 'string',
- 'user.display': 'string',
- 'transaction.duration': 'duration',
- 'project.id': 'integer',
- timestamp: 'date',
- },
- },
- data: [
- {
- id: 'deadbeef',
- 'user.display': 'uhoh@example.com',
- 'transaction.duration': 400,
- 'project.id': 1,
- timestamp: '2020-05-21T15:31:18+00:00',
- trace: '1234',
- 'measurements.lcp': 200,
- },
- {
- id: 'moredeadbeef',
- 'user.display': 'moreuhoh@example.com',
- 'transaction.duration': 600,
- 'project.id': 1,
- timestamp: '2020-05-22T15:31:18+00:00',
- trace: '4321',
- 'measurements.lcp': 300,
- },
- ],
- },
- match: [
- (_url, options) => {
- return options.query?.field?.includes('user.display');
- },
- ],
- });
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/events/',
- body: {
- data: [{'count()': 5161}],
- },
- match: [
- (_url, options) => {
- return options.query?.field?.includes('count()');
- },
- ],
- });
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/events-has-measurements/',
- body: {measurements: false},
- });
- });
- afterEach(function () {
- MockApiClient.clearMockResponses();
- // @ts-ignore no-console
- // eslint-disable-next-line no-console
- console.error.mockRestore();
- act(() => ProjectsStore.reset());
- jest.clearAllMocks();
- });
- it('renders basic UI elements', async function () {
- const initialData = initializeData();
- const wrapper = mountWithTheme(
- <WrappedComponent
- organization={initialData.organization}
- location={initialData.router.location}
- />,
- initialData.routerContext
- );
- await tick();
- wrapper.update();
- expect(
- wrapper.find('NavTabs').find({children: 'All Events'}).find('Link')
- ).toHaveLength(1);
- expect(wrapper.find('SentryDocumentTitle')).toHaveLength(1);
- expect(wrapper.find('SearchBar')).toHaveLength(1);
- expect(wrapper.find('GridEditable')).toHaveLength(1);
- expect(wrapper.find('Pagination')).toHaveLength(1);
- expect(wrapper.find('EventsContent')).toHaveLength(1);
- expect(wrapper.find('TransactionHeader')).toHaveLength(1);
- });
- it('renders relative span breakdown header when no filter selected', async function () {
- const initialData = initializeData();
- const wrapper = mountWithTheme(
- <WrappedComponent
- organization={initialData.organization}
- location={initialData.router.location}
- />,
- initialData.routerContext
- );
- await tick();
- wrapper.update();
- expect(wrapper.find('GridHeadCell')).toHaveLength(6);
- expect(
- wrapper.find('OperationTitle').children().children().children().at(0).html()
- ).toEqual(t('operation duration'));
- });
- it('renders event column results correctly', async function () {
- const initialData = initializeData();
- const wrapper = mountWithTheme(
- <WrappedComponent
- organization={initialData.organization}
- location={initialData.router.location}
- />,
- initialData.routerContext
- );
- await tick();
- wrapper.update();
- function keyAt(index) {
- return wrapper.find('CellAction').at(index).props().column.key;
- }
- function valueAt(index, element = 'div') {
- return wrapper.find('CellAction').at(index).find(element).last().children().html();
- }
- expect(wrapper.find('CellAction')).toHaveLength(12);
- expect(keyAt(0)).toEqual('id');
- expect(valueAt(0)).toEqual('deadbeef');
- expect(keyAt(1)).toEqual('user.display');
- expect(valueAt(1, 'span')).toEqual('uhoh@example.com');
- expect(keyAt(2)).toEqual('span_ops_breakdown.relative');
- expect(valueAt(2, 'span')).toEqual('(no value)');
- expect(keyAt(3)).toEqual('transaction.duration');
- expect(valueAt(3, 'span')).toEqual('400.00ms');
- expect(keyAt(4)).toEqual('trace');
- expect(valueAt(4)).toEqual('1234');
- expect(keyAt(5)).toEqual('timestamp');
- expect(valueAt(5, 'time')).toEqual('May 21, 2020 3:31:18 PM UTC');
- });
- it('renders additional Web Vital column', async function () {
- const initialData = initializeData({
- query: {webVital: WebVital.LCP},
- });
- const wrapper = mountWithTheme(
- <WrappedComponent
- organization={initialData.organization}
- location={initialData.router.location}
- />,
- initialData.routerContext
- );
- await tick();
- wrapper.update();
- function keyAt(index) {
- return wrapper.find('CellAction').at(index).props().column.key;
- }
- function valueAt(index, element = 'div') {
- return wrapper.find('CellAction').at(index).find(element).last().children().html();
- }
- expect(wrapper.find('CellAction')).toHaveLength(14);
- expect(keyAt(0)).toEqual('id');
- expect(valueAt(0)).toEqual('deadbeef');
- expect(keyAt(1)).toEqual('user.display');
- expect(valueAt(1, 'span')).toEqual('uhoh@example.com');
- expect(keyAt(2)).toEqual('span_ops_breakdown.relative');
- expect(valueAt(2, 'span')).toEqual('(no value)');
- expect(keyAt(3)).toEqual('measurements.lcp');
- expect(valueAt(3)).toEqual('200');
- expect(keyAt(4)).toEqual('transaction.duration');
- expect(valueAt(4, 'span')).toEqual('400.00ms');
- expect(keyAt(5)).toEqual('trace');
- expect(valueAt(5)).toEqual('1234');
- expect(keyAt(6)).toEqual('timestamp');
- expect(valueAt(6, 'time')).toEqual('May 21, 2020 3:31:18 PM UTC');
- });
- });
|