import {OrganizationFixture} from 'sentry-fixture/organization'; import {ProjectFixture} from 'sentry-fixture/project'; import {render, screen, waitForElementToBeRemoved} from 'sentry-test/reactTestingLibrary'; import {EntryType} from 'sentry/types/event'; import usePageFilters from 'sentry/utils/usePageFilters'; import {FullSpanDescription} from 'sentry/views/insights/common/components/fullSpanDescription'; import {ModuleName} from 'sentry/views/insights/types'; jest.mock('sentry/utils/usePageFilters'); describe('FullSpanDescription', function () { beforeEach(() => { jest.clearAllMocks(); }); const organization = OrganizationFixture(); const project = ProjectFixture(); jest.mocked(usePageFilters).mockReturnValue({ isReady: true, desyncedFilters: new Set(), pinnedFilters: new Set(), shouldPersist: true, selection: { datetime: { period: '10d', start: null, end: null, utc: false, }, environments: [], projects: [], }, }); const groupId = '2ed2abf6ce7e3577'; const spanId = 'abfed2aabf'; const eventId = '65c7d8647b8a76ef8f4c05d41deb7860'; it('uses the correct code formatting for SQL queries', async function () { MockApiClient.addMockResponse({ url: `/organizations/${organization.slug}/events/`, body: { data: [ { 'transaction.id': eventId, project: project.slug, span_id: spanId, }, ], }, }); MockApiClient.addMockResponse({ url: `/organizations/${organization.slug}/events/${project.slug}:${eventId}/`, body: { id: eventId, entries: [ { type: EntryType.SPANS, data: [ { span_id: spanId, description: 'SELECT users FROM my_table LIMIT 1;', }, ], }, ], }, }); render( , {organization} ); await waitForElementToBeRemoved(() => screen.getByTestId('loading-indicator')); const queryCodeSnippet = await screen.findByText( /select users from my_table limit 1;/i ); expect(queryCodeSnippet).toBeInTheDocument(); expect(queryCodeSnippet).toHaveClass('language-sql'); }); it('uses the correct code formatting for MongoDB queries', async function () { MockApiClient.addMockResponse({ url: `/organizations/${organization.slug}/events/`, body: { data: [ { 'transaction.id': eventId, project: project.slug, span_id: spanId, }, ], }, }); MockApiClient.addMockResponse({ url: `/organizations/${organization.slug}/events/${project.slug}:${eventId}/`, body: { id: eventId, entries: [ { type: EntryType.SPANS, data: [ { span_id: spanId, description: `{"insert": "my_cool_collection😎", "a": {}}`, data: {'db.system': 'mongodb'}, }, ], }, ], }, }); render(, { organization, }); await waitForElementToBeRemoved(() => screen.getByTestId('loading-indicator')); const queryCodeSnippet = screen.getByText( /\{ "insert": "my_cool_collection😎", "a": \{\} \}/i ); expect(queryCodeSnippet).toBeInTheDocument(); expect(queryCodeSnippet).toHaveClass('language-json'); }); it('successfully handles truncated MongoDB queries', async function () { MockApiClient.addMockResponse({ url: `/organizations/${organization.slug}/events/`, body: { data: [ { 'transaction.id': eventId, project: project.slug, span_id: spanId, }, ], }, }); MockApiClient.addMockResponse({ url: `/organizations/${organization.slug}/events/${project.slug}:${eventId}/`, body: { id: eventId, entries: [ { type: EntryType.SPANS, data: [ { span_id: spanId, description: `{"insert": "my_cool_collection😎", "a": {}, "uh_oh":"the_query_is_truncated", "ohno*`, data: {'db.system': 'mongodb'}, }, ], }, ], }, }); render(, { organization, }); await waitForElementToBeRemoved(() => screen.getByTestId('loading-indicator')); // The last truncated entry will have a null value assigned and the JSON document is properly closed const queryCodeSnippet = screen.getByText( /\{ "insert": "my_cool_collection😎", "a": \{\}, "uh_oh": "the_query_is_truncated", "ohno\*": null \}/i ); expect(queryCodeSnippet).toBeInTheDocument(); expect(queryCodeSnippet).toHaveClass('language-json'); }); });