import {mountWithTheme} from 'sentry-test/enzyme'; import {initializeOrg} from 'sentry-test/initializeOrg'; import QuickTrace from 'sentry/components/quickTrace'; import {Event} from 'sentry/types/event'; import {QuickTraceEvent} from 'sentry/utils/performance/quickTrace/types'; describe('Quick Trace', function () { let location; let organization; const initialize = () => { const context = initializeOrg(); organization = context.organization; }; function makeQuickTraceEvents(generation, {n = 1, parentId = null} = {}) { const events: QuickTraceEvent[] = []; for (let i = 0; i < n; i++) { const suffix = n > 1 ? `-${i}` : ''; events.push({ event_id: `e${generation}${suffix}`, generation, span_id: `s${generation}${suffix}`, transaction: `t${generation}${suffix}`, 'transaction.duration': 1234, project_id: generation, project_slug: `p${generation}`, parent_event_id: generation === 0 ? null : parentId === null ? `e${generation - 1}` : parentId, parent_span_id: generation === 0 ? null : parentId === null ? `s${generation - 1}${parentId}` : `s${parentId}`, }); } return events; } function makeTransactionEvent(id) { return { id: `e${id}`, type: 'transaction', startTimestamp: 1615921516.132774, endTimestamp: 1615921517.924861, }; } function makeTransactionTarget( pid: string, eid: string, transaction: string, project: string ) { const query = {transaction, project}; return { pathname: `/organizations/${organization.slug}/performance/${pid}:${eid}/`, query, }; } beforeEach(function () { initialize(); location = { pathname: '/', query: {}, }; }); describe('Empty Trace', function () { it('renders nothing for empty trace', function () { const quickTrace = mountWithTheme( ); expect(quickTrace.text()).toEqual('\u2014'); }); }); describe('Partial Trace', function () { it('renders nothing when partial trace is empty', function () { const quickTrace = mountWithTheme( ); expect(quickTrace.text()).toEqual('\u2014'); }); it('renders nothing when partial trace missing current event', function () { const quickTrace = mountWithTheme( ); expect(quickTrace.text()).toEqual('\u2014'); }); it('renders partial trace with no children', function () { const quickTrace = mountWithTheme( ); const nodes = quickTrace.find('EventNode'); expect(nodes.length).toEqual(1); expect(nodes.first().text()).toEqual('This Event'); }); it('renders partial trace with single child', function () { const quickTrace = mountWithTheme( ); const nodes = quickTrace.find('EventNode'); expect(nodes.length).toEqual(2); ['This Event', '1 Child'].forEach((text, i) => expect(nodes.at(i).text()).toEqual(text) ); }); it('renders partial trace with multiple children', function () { const quickTrace = mountWithTheme( ); const nodes = quickTrace.find('EventNode'); expect(nodes.length).toEqual(2); ['This Event', '3 Children'].forEach((text, i) => expect(nodes.at(i).text()).toEqual(text) ); }); it('renders full trace with root as parent', function () { const quickTrace = mountWithTheme( ); const nodes = quickTrace.find('EventNode'); expect(nodes.length).toEqual(2); ['Parent', 'This Event'].forEach((text, i) => expect(nodes.at(i).text()).toEqual(text) ); }); }); describe('Full Trace', function () { it('renders full trace with single ancestor', function () { const quickTrace = mountWithTheme( ); const nodes = quickTrace.find('EventNode'); expect(nodes.length).toEqual(4); ['Root', '1 Ancestor', 'Parent', 'This Event'].forEach((text, i) => expect(nodes.at(i).text()).toEqual(text) ); }); it('renders full trace with multiple ancestors', function () { const quickTrace = mountWithTheme( ); const nodes = quickTrace.find('EventNode'); expect(nodes.length).toEqual(4); ['Root', '3 Ancestors', 'Parent', 'This Event'].forEach((text, i) => expect(nodes.at(i).text()).toEqual(text) ); }); it('renders full trace with single descendant', function () { const quickTrace = mountWithTheme( ); const nodes = quickTrace.find('EventNode'); expect(nodes.length).toEqual(3); ['This Event', '1 Child', '1 Descendant'].forEach((text, i) => expect(nodes.at(i).text()).toEqual(text) ); }); it('renders full trace with multiple descendants', function () { const quickTrace = mountWithTheme( ); const nodes = quickTrace.find('EventNode'); expect(nodes.length).toEqual(3); ['This Event', '1 Child', '3 Descendants'].forEach((text, i) => expect(nodes.at(i).text()).toEqual(text) ); }); it('renders full trace', function () { const quickTrace = mountWithTheme( ); const nodes = quickTrace.find('EventNode'); expect(nodes.length).toEqual(6); ['Root', '3 Ancestors', 'Parent', 'This Event', '1 Child', '3 Descendants'].forEach( (text, i) => expect(nodes.at(i).text()).toEqual(text) ); }); }); describe('Event Node Clicks', function () { it('renders single event targets', function () { const quickTrace = mountWithTheme( ); const nodes = quickTrace.find('EventNode'); expect(nodes.length).toEqual(6); [ makeTransactionTarget('p0', 'e0', 't0', '0'), makeTransactionTarget('p1', 'e1', 't1', '1'), makeTransactionTarget('p2', 'e2', 't2', '2'), undefined, // the "This Event" node has no target makeTransactionTarget('p4', 'e4', 't4', '4'), makeTransactionTarget('p5', 'e5', 't5', '5'), ].forEach((target, i) => expect(nodes.at(i).props().to).toEqual(target)); }); it('renders multiple event targets', function () { const quickTrace = mountWithTheme( ); const items = quickTrace.find('DropdownItem'); expect(items.length).toEqual(3); // can't easily assert the target is correct since it uses an onClick handler }); }); });