123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- import {OrganizationFixture} from 'sentry-fixture/organization';
- import {RouterFixture} from 'sentry-fixture/routerFixture';
- import {render, screen} from 'sentry-test/reactTestingLibrary';
- import {GroupRelatedIssues} from 'sentry/views/issueDetails/groupRelatedIssues';
- describe('Related Issues View', function () {
- let sameRootIssuesMock: jest.Mock;
- let traceIssuesMock: jest.Mock;
- let issuesMock: jest.Mock;
- const router = RouterFixture();
- const organization = OrganizationFixture();
- const orgSlug = organization.slug;
- const groupId = '12345678';
- const group1 = '15';
- const group2 = '20';
- // query=issue.id:[15,20] -> query=issue.id%3A%5B15%2C20%5D
- const orgIssuesEndpoint = `/organizations/${orgSlug}/issues/?query=issue.id%3A%5B${group1}%2C${group2}%5D`;
- const params = {groupId: groupId};
- const errorType = 'RuntimeError';
- const noData = {
- type: 'irrelevant',
- data: [],
- };
- const onlySameRootData = {
- type: 'same_root_cause',
- data: [group1, group2],
- };
- const onlyTraceConnectedData = {
- type: 'trace_connected',
- data: [group1, group2],
- meta: {
- event_id: 'abcd',
- trace_id: '1234',
- },
- };
- const issuesData = [
- {
- id: group1,
- shortId: `EARTH-${group1}`,
- project: {id: '3', name: 'Earth', slug: 'earth', platform: null},
- type: 'error',
- metadata: {
- type: errorType,
- },
- issueCategory: 'error',
- lastSeen: '2024-03-15T20:15:30Z',
- },
- {
- id: group2,
- shortId: `EARTH-${group2}`,
- project: {id: '3', name: 'Earth', slug: 'earth', platform: null},
- type: 'error',
- metadata: {
- type: errorType,
- },
- issueCategory: 'error',
- lastSeen: '2024-03-16T20:15:30Z',
- },
- ];
- beforeEach(function () {
- // GroupList calls this but we don't need it for this test
- MockApiClient.addMockResponse({
- url: `/organizations/${orgSlug}/users/`,
- body: {},
- });
- });
- afterEach(() => {
- MockApiClient.clearMockResponses();
- jest.clearAllMocks();
- });
- it('renders with no data', async function () {
- sameRootIssuesMock = MockApiClient.addMockResponse({
- url: `/issues/${groupId}/related-issues/?type=same_root_cause`,
- body: noData,
- });
- traceIssuesMock = MockApiClient.addMockResponse({
- url: `/issues/${groupId}/related-issues/?type=trace_connected`,
- body: noData,
- });
- render(
- <GroupRelatedIssues
- params={params}
- location={router.location}
- router={router}
- routeParams={router.params}
- routes={router.routes}
- route={{}}
- />
- );
- expect(
- await screen.findByText('No same-root-cause related issues were found.')
- ).toBeInTheDocument();
- expect(
- await screen.findByText('No trace-connected related issues were found.')
- ).toBeInTheDocument();
- expect(sameRootIssuesMock).toHaveBeenCalled();
- expect(traceIssuesMock).toHaveBeenCalled();
- });
- it('renders with same root issues', async function () {
- sameRootIssuesMock = MockApiClient.addMockResponse({
- url: `/issues/${groupId}/related-issues/?type=same_root_cause`,
- body: onlySameRootData,
- });
- MockApiClient.addMockResponse({
- url: `/issues/${groupId}/related-issues/?type=trace_connected`,
- body: [],
- });
- issuesMock = MockApiClient.addMockResponse({
- url: orgIssuesEndpoint,
- body: issuesData,
- });
- render(
- <GroupRelatedIssues
- params={params}
- location={router.location}
- router={router}
- routeParams={router.params}
- routes={router.routes}
- route={{}}
- />
- );
- // Wait for the issues showing up on the table
- expect(await screen.findByText(`EARTH-${group1}`)).toBeInTheDocument();
- expect(await screen.findByText(`EARTH-${group2}`)).toBeInTheDocument();
- expect(sameRootIssuesMock).toHaveBeenCalled();
- expect(issuesMock).toHaveBeenCalled();
- expect(
- await screen.findByText('No trace-connected related issues were found.')
- ).toBeInTheDocument();
- const linkButton = screen.getByRole('button', {name: /open in issues/i});
- expect(linkButton).toHaveAttribute(
- 'href',
- // Opening in Issues needs to include the group we are currently viewing
- `/organizations/org-slug/issues/?project=-1&query=issue.id:[${groupId},${group1},${group2}]`
- );
- });
- it('renders with trace connected issues', async function () {
- MockApiClient.addMockResponse({
- url: `/issues/${groupId}/related-issues/?type=same_root_cause`,
- body: [],
- });
- traceIssuesMock = MockApiClient.addMockResponse({
- url: `/issues/${groupId}/related-issues/?type=trace_connected`,
- body: onlyTraceConnectedData,
- });
- issuesMock = MockApiClient.addMockResponse({
- url: orgIssuesEndpoint,
- body: issuesData,
- });
- render(
- <GroupRelatedIssues
- params={params}
- location={router.location}
- router={router}
- routeParams={router.params}
- routes={router.routes}
- route={{}}
- />
- );
- // Wait for the issues showing up on the table
- expect(await screen.findByText(`EARTH-${group1}`)).toBeInTheDocument();
- expect(await screen.findByText(`EARTH-${group2}`)).toBeInTheDocument();
- expect(traceIssuesMock).toHaveBeenCalled();
- expect(issuesMock).toHaveBeenCalled();
- expect(
- await screen.findByText('No same-root-cause related issues were found.')
- ).toBeInTheDocument();
- const linkElement = screen.getByRole('link', {name: /this trace/i});
- expect(linkElement).toHaveAttribute(
- 'href',
- '/organizations/org-slug/performance/trace/1234/?node=error-abcd'
- );
- const linkButton = screen.getByRole('button', {name: /open in issues/i});
- // The Issue search supports using `trace` as a parameter
- expect(linkButton).toHaveAttribute(
- 'href',
- `/organizations/org-slug/issues/?project=-1&query=trace:1234`
- );
- });
- });
|