import {EventAttachmentFixture} from 'sentry-fixture/eventAttachment';
import {ProjectFixture} from 'sentry-fixture/project';
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 ProjectsStore from 'sentry/stores/projectsStore';
import type {Project} from 'sentry/types/project';
import GroupEventAttachments from './groupEventAttachments';
describe('GroupEventAttachments', function () {
const groupId = 'group-id';
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();
getAttachmentsMock = MockApiClient.addMockResponse({
url: `/organizations/org-slug/issues/${groupId}/attachments/`,
body: [EventAttachmentFixture()],
});
});
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('does not render screenshots tab if not mobile platform', function () {
project.platform = 'javascript';
render(, {
router: screenshotRouter,
organization,
});
expect(screen.queryByText('Screenshots')).not.toBeInTheDocument();
});
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();
});
});