import {EnvironmentsFixture} from 'sentry-fixture/environments'; import {EventAttachmentFixture} from 'sentry-fixture/eventAttachment'; import {GroupFixture} from 'sentry-fixture/group'; import {ProjectFixture} from 'sentry-fixture/project'; import {RouterFixture} from 'sentry-fixture/routerFixture'; import {TagsFixture} from 'sentry-fixture/tags'; import {initializeOrg} from 'sentry-test/initializeOrg'; import { render, renderGlobalModal, screen, userEvent, within, } from 'sentry-test/reactTestingLibrary'; import GroupStore from 'sentry/stores/groupStore'; import ModalStore from 'sentry/stores/modalStore'; import PageFiltersStore from 'sentry/stores/pageFiltersStore'; import ProjectsStore from 'sentry/stores/projectsStore'; import type {Project} from 'sentry/types/project'; import GroupEventAttachments from './groupEventAttachments'; describe('GroupEventAttachments', function () { const groupId = 'group-id'; const group = GroupFixture({id: groupId}); const {organization, router} = initializeOrg({ organization: { features: ['event-attachments'], orgRole: 'member', attachmentsRole: 'member', }, }); const {router: screenshotRouter} = initializeOrg({ router: { params: {orgId: 'org-slug', groupId: 'group-id'}, location: {query: {attachmentFilter: 'screenshot'}}, }, }); let project: Project; let getAttachmentsMock: jest.Mock; beforeEach(function () { project = ProjectFixture({platform: 'apple-ios'}); ProjectsStore.loadInitialData([project]); GroupStore.init(); MockApiClient.addMockResponse({ url: `/organizations/${organization.slug}/environments/`, body: EnvironmentsFixture(), }); getAttachmentsMock = MockApiClient.addMockResponse({ url: `/organizations/org-slug/issues/${groupId}/attachments/`, body: [EventAttachmentFixture()], }); MockApiClient.addMockResponse({ url: `/organizations/${organization.slug}/issues/${group.id}/tags/`, body: TagsFixture(), method: 'GET', }); }); afterEach(() => { MockApiClient.clearMockResponses(); ModalStore.reset(); }); it('calls attachments api with screenshot filter', async function () { render(, { router: screenshotRouter, organization, }); expect(screen.getByRole('radio', {name: 'Screenshots'})).toBeInTheDocument(); await userEvent.click(screen.getByRole('radio', {name: 'Screenshots'})); expect(getAttachmentsMock).toHaveBeenCalledWith( '/organizations/org-slug/issues/group-id/attachments/', expect.objectContaining({ query: {screenshot: '1'}, }) ); }); it('calls opens modal when clicking on panel body', async function () { render(, { router: screenshotRouter, organization, }); renderGlobalModal(); await userEvent.click(await screen.findByTestId('screenshot-1')); expect(await screen.findByRole('dialog')).toBeInTheDocument(); }); it('links event id to event detail', async function () { render(, { router, organization, }); expect(await screen.findByRole('link', {name: '12345678'})).toHaveAttribute( 'href', '/organizations/org-slug/issues/group-id/events/12345678901234567890123456789012/' ); }); it('links to the download URL', async function () { render(, { router: screenshotRouter, organization, }); await userEvent.click(await screen.findByLabelText('Actions')); expect( await screen.findByRole('menuitemradio', {name: 'Download'}) ).toBeInTheDocument(); }); it('displays error message when request fails', async function () { MockApiClient.addMockResponse({ url: '/organizations/org-slug/issues/group-id/attachments/', statusCode: 500, }); render(, { router, organization, }); expect(await screen.findByText(/error loading/i)).toBeInTheDocument(); }); it('can delete an attachment', async function () { const deleteMock = MockApiClient.addMockResponse({ url: '/projects/org-slug/project-slug/events/12345678901234567890123456789012/attachments/1/', method: 'DELETE', }); render(, { router, organization, }); renderGlobalModal(); expect(await screen.findByText('12345678')).toBeInTheDocument(); expect(screen.getByRole('button', {name: 'Delete'})).toBeEnabled(); await userEvent.click(screen.getByRole('button', {name: 'Delete'})); expect( await screen.findByText('Are you sure you wish to delete this file?') ).toBeInTheDocument(); await userEvent.click( within(screen.getByRole('dialog')).getByRole('button', {name: 'Delete'}) ); expect(deleteMock).toHaveBeenCalled(); expect(screen.queryByText('12345678')).not.toBeInTheDocument(); }); it('filters by date/query when using Streamlined UI', function () { PageFiltersStore.init(); PageFiltersStore.onInitializeUrlState( { projects: [parseInt(project.id, 10)], environments: ['staging'], datetime: { period: '3d', start: null, end: null, utc: null, }, }, new Set() ); const testRouter = RouterFixture(); testRouter.location.query = { query: 'user.email:leander.rodrigues@sentry.io', }; render(, { router: testRouter, organization: {...organization, features: ['issue-details-streamline-enforce']}, }); expect(getAttachmentsMock).toHaveBeenCalledWith( '/organizations/org-slug/issues/group-id/attachments/', expect.objectContaining({ query: { environment: ['staging'], query: 'user.email:leander.rodrigues@sentry.io', statsPeriod: '3d', }, }) ); }); });