import {OrganizationFixture} from 'sentry-fixture/organization';
import {SourceMapArchiveFixture} from 'sentry-fixture/sourceMapArchive';
import {SourceMapArtifactFixture} from 'sentry-fixture/sourceMapArtifact';
import {SourceMapsDebugIDBundlesArtifactsFixture} from 'sentry-fixture/sourceMapsDebugIDBundlesArtifacts';
import {UserFixture} from 'sentry-fixture/user';
import {initializeOrg} from 'sentry-test/initializeOrg';
import {
render,
renderGlobalModal,
screen,
userEvent,
waitFor,
} from 'sentry-test/reactTestingLibrary';
import {textWithMarkupMatcher} from 'sentry-test/utils';
import ConfigStore from 'sentry/stores/configStore';
import OrganizationStore from 'sentry/stores/organizationStore';
import {SourceMapsDetails} from 'sentry/views/settings/projectSourceMaps/sourceMapsDetails';
function renderReleaseBundlesMockRequests({
orgSlug,
projectSlug,
empty,
}: {
orgSlug: string;
projectSlug: string;
empty?: boolean;
}) {
const sourceMaps = MockApiClient.addMockResponse({
url: `/projects/${orgSlug}/${projectSlug}/files/source-maps/`,
body: empty
? []
: [
SourceMapArchiveFixture(),
SourceMapArchiveFixture({
id: 2,
name: 'abc',
fileCount: 3,
date: '2023-05-06T13:41:00Z',
}),
],
});
const sourceMapsFiles = MockApiClient.addMockResponse({
url: `/projects/${orgSlug}/${projectSlug}/releases/bea7335dfaebc0ca6e65a057/files/`,
body: empty ? [] : [SourceMapArtifactFixture()],
});
return {sourceMaps, sourceMapsFiles};
}
function renderDebugIdBundlesMockRequests({
orgSlug,
projectSlug,
empty,
}: {
orgSlug: string;
projectSlug: string;
empty?: boolean;
}) {
const artifactBundlesFiles = MockApiClient.addMockResponse({
url: `/projects/${orgSlug}/${projectSlug}/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/files/`,
body: SourceMapsDebugIDBundlesArtifactsFixture(
empty
? {
fileCount: 0,
associations: [],
files: [],
}
: {}
),
});
const artifactBundlesDeletion = MockApiClient.addMockResponse({
url: `/projects/${orgSlug}/${projectSlug}/files/artifact-bundles/`,
method: 'DELETE',
});
return {artifactBundlesFiles, artifactBundlesDeletion};
}
describe('SourceMapsDetails', function () {
beforeEach(function () {
OrganizationStore.init();
});
describe('Release Bundles', function () {
it('renders default state', async function () {
const {organization, router, project, routerProps} = initializeOrg({
organization: OrganizationFixture({
access: ['org:superuser'],
}),
router: {
location: {
query: {},
},
params: {},
},
});
OrganizationStore.onUpdate(organization, {replace: true});
ConfigStore.set('user', UserFixture({isSuperuser: true}));
renderReleaseBundlesMockRequests({
orgSlug: organization.slug,
projectSlug: project.slug,
});
render(
,
{router, organization}
);
// Title
expect(screen.getByRole('heading')).toHaveTextContent('Release Bundle');
// Subtitle
expect(screen.getByText('bea7335dfaebc0ca6e65a057')).toBeInTheDocument();
// Search bar
expect(screen.getByPlaceholderText('Filter by Path')).toBeInTheDocument();
// Path
expect(
await screen.findByText('https://example.com/AcceptOrganizationInvite.js')
).toBeInTheDocument();
// Time
expect(screen.getByText(/in 3 year/)).toBeInTheDocument();
// File size
expect(screen.getByText('8.1 KiB')).toBeInTheDocument();
// Download button
expect(screen.getByRole('button', {name: 'Download Artifact'})).toHaveAttribute(
'href',
'/projects/org-slug/project-slug/releases/bea7335dfaebc0ca6e65a057/files/5678/?download=1'
);
});
it('renders empty state', async function () {
const {organization, routerProps, project, router} = initializeOrg({
router: {
location: {
query: {},
},
params: {},
},
});
renderReleaseBundlesMockRequests({
orgSlug: organization.slug,
projectSlug: project.slug,
empty: true,
});
render(
,
{router, organization}
);
expect(
await screen.findByText('There are no artifacts in this upload.')
).toBeInTheDocument();
});
});
describe('Artifact Bundles', function () {
it('renders default state', async function () {
const {organization, project, routerProps, router} = initializeOrg({
organization: OrganizationFixture({
access: ['org:superuser', 'project:releases'],
}),
router: {
location: {
pathname: `/settings/${initializeOrg().organization.slug}/projects/${
initializeOrg().project.slug
}/source-maps/7227e105-744e-4066-8c69-3e5e344723fc/`,
query: {},
},
params: {},
},
});
OrganizationStore.onUpdate(organization, {replace: true});
ConfigStore.set('user', UserFixture({isSuperuser: true}));
const mockRequests = renderDebugIdBundlesMockRequests({
orgSlug: organization.slug,
projectSlug: project.slug,
});
render(
,
{router, organization}
);
// Title
expect(screen.getByRole('heading')).toHaveTextContent(
'7227e105-744e-4066-8c69-3e5e344723fc'
);
// Details
// Artifacts
expect(await screen.findByText('Artifacts')).toBeInTheDocument();
expect(await screen.findByText('22')).toBeInTheDocument();
// Release information
expect(await screen.findByText('Associated Releases')).toBeInTheDocument();
expect(
await screen.findByText(textWithMarkupMatcher('v2.0 (Dist: none)'))
).toBeInTheDocument();
expect(
await screen.findByText(
textWithMarkupMatcher(
'frontend@2e318148eac9298ec04a662ae32b4b093b027f0a (Dist: android, iOS)'
)
)
).toBeInTheDocument();
// Date Uploaded
expect(await screen.findByText('Date Uploaded')).toBeInTheDocument();
expect(await screen.findByText('Mar 8, 2023 9:53 AM UTC')).toBeInTheDocument();
// Search bar
expect(screen.getByPlaceholderText('Filter by Path or ID')).toBeInTheDocument();
// Path
expect(await screen.findByText('files/_/_/main.js')).toBeInTheDocument();
// Debug Id
expect(
screen.getByText('69ac68eb-cc62-44c0-a5dc-b67f219a3696')
).toBeInTheDocument();
// Type
expect(screen.getByText('Minified')).toBeInTheDocument();
// Download Button
expect(screen.getByRole('button', {name: 'Download Artifact'})).toHaveAttribute(
'href',
'/projects/org-slug/project-slug/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/files/ZmlsZXMvXy9fL21haW4uanM=/?download=1'
);
renderGlobalModal();
// Delete item displays a confirmation modal
await userEvent.click(screen.getByRole('button', {name: 'Delete Source Maps'}));
expect(
await screen.findByText('Are you sure you want to delete these source maps?')
).toBeInTheDocument();
// Close modal
await userEvent.click(screen.getByRole('button', {name: 'Confirm'}));
await waitFor(() => {
expect(mockRequests.artifactBundlesDeletion).toHaveBeenLastCalledWith(
'/projects/org-slug/project-slug/files/artifact-bundles/',
expect.objectContaining({
query: expect.objectContaining({
bundleId: '7227e105-744e-4066-8c69-3e5e344723fc',
}),
})
);
});
});
it('renders empty state', async function () {
const {organization, project, routerProps, router} = initializeOrg({
router: {
location: {
pathname: `/settings/${initializeOrg().organization.slug}/projects/${
initializeOrg().project.slug
}/source-maps/7227e105-744e-4066-8c69-3e5e344723fc/`,
query: {},
},
params: {},
},
});
renderDebugIdBundlesMockRequests({
orgSlug: organization.slug,
projectSlug: project.slug,
empty: true,
});
render(
,
{router, organization}
);
expect(
await screen.findByText('There are no artifacts in this upload.')
).toBeInTheDocument();
expect(
screen.getByText('No releases associated with this upload.')
).toBeInTheDocument();
});
});
});