diff --git a/static/app/components/events/interfaces/frame/context.spec.tsx b/static/app/components/events/interfaces/frame/context.spec.tsx index d5179d1915bc8f..609c05b9209281 100644 --- a/static/app/components/events/interfaces/frame/context.spec.tsx +++ b/static/app/components/events/interfaces/frame/context.spec.tsx @@ -6,10 +6,8 @@ import {render, screen} from 'sentry-test/reactTestingLibrary'; import {ProjectsStore} from 'sentry/stores/projectsStore'; import type {Frame} from 'sentry/types/event'; -import type {LineCoverage} from 'sentry/types/integrations'; -import {CodecovStatusCode, Coverage} from 'sentry/types/integrations'; -import {Context, getLineCoverage} from './context'; +import {Context} from './context'; describe('Frame - Context', () => { const org = OrganizationFixture(); @@ -22,50 +20,8 @@ describe('Frame - Context', () => { ProjectsStore.loadInitialData([project]); }); - const lines: Array<[number, string]> = [ - [231, 'this is line 231'], - [232, 'this is line 232'], - [233, 'this is line 233'], - [234, 'this is line 234'], - ]; - - const lineCoverage: LineCoverage[] = [ - [230, Coverage.PARTIAL], - [231, Coverage.PARTIAL], - [232, Coverage.COVERED], - [234, Coverage.NOT_COVERED], - ]; - - it("gets coverage data for the frame's lines", () => { - expect(getLineCoverage(lines, lineCoverage)).toEqual([ - [Coverage.PARTIAL, Coverage.COVERED, undefined, Coverage.NOT_COVERED], - true, - ]); - }); - - it("doesn't query stacktrace coverage if the flag is off", () => { - const mock = MockApiClient.addMockResponse({ - url: `/projects/${org.slug}/${project.slug}/stacktrace-coverage/`, - body: {status: CodecovStatusCode.NO_COVERAGE_DATA}, - }); - render(, { - organization: org, - }); - - expect(mock).not.toHaveBeenCalled(); - }); - describe('syntax highlighting', () => { it('renders code correctly when context lines end in newline characters', () => { - const organization = { - ...org, - codecovAccess: true, - }; - MockApiClient.addMockResponse({ - url: `/projects/${org.slug}/${project.slug}/stacktrace-coverage/`, - body: {status: CodecovStatusCode.NO_COVERAGE_DATA}, - }); - const testFrame: Frame = { ...frame, lineNo: 2, @@ -85,7 +41,7 @@ describe('Frame - Context', () => { registers={{}} components={[]} />, - {organization} + {organization: org} ); expect(screen.getAllByTestId('context-line')).toHaveLength(3); diff --git a/static/app/components/events/interfaces/frame/context.tsx b/static/app/components/events/interfaces/frame/context.tsx index 55ef63c5064bcd..4b5c0736a9e121 100644 --- a/static/app/components/events/interfaces/frame/context.tsx +++ b/static/app/components/events/interfaces/frame/context.tsx @@ -1,6 +1,5 @@ import {Fragment, useMemo} from 'react'; import styled from '@emotion/styled'; -import keyBy from 'lodash/keyBy'; import {ClippedBox} from 'sentry/components/clippedBox'; import {parseAssembly} from 'sentry/components/events/interfaces/utils'; @@ -9,16 +8,13 @@ import {IconFlag} from 'sentry/icons'; import {t} from 'sentry/locale'; import type {Event, Frame} from 'sentry/types/event'; import type { - LineCoverage, SentryAppComponent, SentryAppSchemaStacktraceLink, } from 'sentry/types/integrations'; -import {CodecovStatusCode, Coverage} from 'sentry/types/integrations'; import type {PlatformKey} from 'sentry/types/project'; import type {StacktraceType} from 'sentry/types/stacktrace'; import {defined} from 'sentry/utils'; import {getFileExtension} from 'sentry/utils/fileExtension'; -import {useRouteAnalyticsParams} from 'sentry/utils/routeAnalytics/useRouteAnalyticsParams'; import {useOrganization} from 'sentry/utils/useOrganization'; import {useProjects} from 'sentry/utils/useProjects'; @@ -28,7 +24,6 @@ import {FrameRegisters} from './frameRegisters'; import {FrameVariables} from './frameVariables'; import {usePrismTokensSourceContext} from './usePrismTokensSourceContext'; import {useSourceContext} from './useSourceContext'; -import {useStacktraceCoverage} from './useStacktraceCoverage'; import {hasPotentialSourceContext} from './utils'; type Props = { @@ -50,21 +45,6 @@ type Props = { registersMeta?: Record; }; -export function getLineCoverage( - lines: Frame['context'], - lineCov: LineCoverage[] -): [Array, boolean] { - const keyedCoverage = keyBy(lineCov, 0); - const lineCoverage = lines.map( - ([lineNo]) => keyedCoverage[lineNo]?.[1] - ); - const hasCoverage = lineCoverage.some( - coverage => coverage !== Coverage.NOT_APPLICABLE && coverage !== undefined - ); - - return [lineCoverage, hasCoverage]; -} - export function Context({ hasContextVars = false, hasContextSource = false, @@ -117,22 +97,6 @@ export function Context({ const effectiveContext = hasContextSource ? frame?.context : scmContext; const effectiveHasContextSource = hasContextSource || !!scmContext?.length; - const {data: coverage, isPending: isLoadingCoverage} = useStacktraceCoverage( - { - event, - frame, - orgSlug: organization?.slug || '', - projectSlug: project?.slug, - }, - { - enabled: - defined(organization) && - defined(project) && - !!organization.codecovAccess && - isExpanded, - } - ); - /** * frame.lineNo is the highlighted frame in the middle of the context */ @@ -141,22 +105,6 @@ export function Context({ ? effectiveContext : effectiveContext?.filter(l => l[0] === activeLineNumber); - const hasCoverageData = - !isLoadingCoverage && coverage?.status === CodecovStatusCode.COVERAGE_EXISTS; - - const [lineCoverage = [], hasCoverage] = - hasCoverageData && coverage?.lineCoverage && !!activeLineNumber! && contextLines - ? getLineCoverage(contextLines, coverage.lineCoverage) - : []; - - useRouteAnalyticsParams( - hasCoverageData - ? { - has_line_coverage: hasCoverage, - } - : {} - ); - const fileExtension = getFileExtension(frame.filename || frame.absPath || '') ?? ''; const lines = usePrismTokensSourceContext({ contextLines, @@ -211,7 +159,6 @@ export function Context({ {line.map((token, key) => ( diff --git a/static/app/components/events/interfaces/frame/contextLineNumber.tsx b/static/app/components/events/interfaces/frame/contextLineNumber.tsx index 4ef2b623df1c94..14d8b5e41b8525 100644 --- a/static/app/components/events/interfaces/frame/contextLineNumber.tsx +++ b/static/app/components/events/interfaces/frame/contextLineNumber.tsx @@ -1,41 +1,15 @@ import styled from '@emotion/styled'; -import classNames from 'classnames'; - -import {Tooltip} from '@sentry/scraps/tooltip'; - -import {t} from 'sentry/locale'; -import {Coverage} from 'sentry/types/integrations'; interface Props { isActive: boolean; lineNumber: number; children?: React.ReactNode; - coverage?: Coverage; } -const coverageText: Record = { - [Coverage.NOT_COVERED]: t('Line uncovered by tests'), - [Coverage.COVERED]: t('Line covered by tests'), - [Coverage.PARTIAL]: t('Line partially covered by tests'), - [Coverage.NOT_APPLICABLE]: undefined, -}; -const coverageClass: Record = { - [Coverage.NOT_COVERED]: 'uncovered', - [Coverage.COVERED]: 'covered', - [Coverage.PARTIAL]: 'partial', - [Coverage.NOT_APPLICABLE]: undefined, -}; - -export function ContextLineNumber({ - lineNumber, - isActive, - coverage = Coverage.NOT_APPLICABLE, -}: Props) { +export function ContextLineNumber({lineNumber, isActive}: Props) { return ( - - -
{lineNumber}
-
+ +
{lineNumber}
); } @@ -65,38 +39,7 @@ const Wrapper = styled('div')` user-select: none; } - &.covered .line-number { - background: ${p => p.theme.colors.green100}; - border-right: 3px solid ${p => p.theme.tokens.border.success.vibrant}; - } - - &.uncovered .line-number { - background: ${p => p.theme.colors.red100}; - border-right: 3px solid ${p => p.theme.tokens.border.danger.vibrant}; - } - - &.partial .line-number { - background: ${p => p.theme.colors.yellow100}; - border-right: 3px dashed ${p => p.theme.tokens.border.warning.vibrant}; - } - &.active { background: none; } - - &.active.partial .line-number { - mix-blend-mode: screen; - background: ${p => p.theme.colors.yellow200}; - } - - &.active.covered .line-number { - mix-blend-mode: screen; - background: ${p => p.theme.colors.green200}; - } - - &.active.uncovered .line-number { - color: ${p => p.theme.colors.white}; - mix-blend-mode: screen; - background: ${p => p.theme.colors.red400}; - } `; diff --git a/static/app/components/events/interfaces/frame/stacktraceLink.spec.tsx b/static/app/components/events/interfaces/frame/stacktraceLink.spec.tsx index 88d6badb923d49..440fae5e8bff16 100644 --- a/static/app/components/events/interfaces/frame/stacktraceLink.spec.tsx +++ b/static/app/components/events/interfaces/frame/stacktraceLink.spec.tsx @@ -7,13 +7,11 @@ import {ReleaseFixture} from 'sentry-fixture/release'; import {RepositoryFixture} from 'sentry-fixture/repository'; import {RepositoryProjectPathConfigFixture} from 'sentry-fixture/repositoryProjectPathConfig'; -import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary'; +import {render, screen, waitFor} from 'sentry-test/reactTestingLibrary'; import {HookStore} from 'sentry/stores/hookStore'; import {ProjectsStore} from 'sentry/stores/projectsStore'; import type {Frame} from 'sentry/types/event'; -import {CodecovStatusCode} from 'sentry/types/integrations'; -import * as analytics from 'sentry/utils/analytics'; import {StacktraceLink} from './stacktraceLink'; @@ -32,8 +30,6 @@ describe('StacktraceLink', () => { const frame = {filename: '/sentry/app.py', lineNo: 233, inApp: true} as Frame; const config = RepositoryProjectPathConfigFixture({project, repo, integration}); - const analyticsSpy = jest.spyOn(analytics, 'trackAnalytics'); - beforeEach(() => { jest.clearAllMocks(); MockApiClient.clearMockResponses(); @@ -123,105 +119,6 @@ describe('StacktraceLink', () => { expect(await screen.findByText('Set up Code Mapping')).toBeInTheDocument(); }); - it('renders the codecov link', async () => { - const organization = { - ...org, - codecovAccess: true, - features: ['codecov-integration'], - }; - MockApiClient.addMockResponse({ - url: `/projects/${org.slug}/${project.slug}/stacktrace-link/`, - body: { - config, - sourceUrl: 'https://github.com/username/path/to/file.py', - integrations: [integration], - }, - }); - MockApiClient.addMockResponse({ - url: `/projects/${org.slug}/${project.slug}/stacktrace-coverage/`, - body: { - status: CodecovStatusCode.COVERAGE_EXISTS, - lineCoverage: [[233, 0]], - coverageUrl: 'https://app.codecov.io/gh/path/to/file.py', - }, - }); - render( - , - { - organization, - } - ); - - const link = await screen.findByRole('button', {name: 'Open in Codecov'}); - expect(link).toHaveAttribute( - 'href', - 'https://app.codecov.io/gh/path/to/file.py#L233' - ); - - await userEvent.click(link); - expect(analyticsSpy).toHaveBeenCalledWith( - 'integrations.stacktrace_codecov_link_clicked', - expect.anything() - ); - }); - - it('renders the missing coverage warning', async () => { - const organization = { - ...org, - codecovAccess: true, - features: ['codecov-integration'], - }; - MockApiClient.addMockResponse({ - url: `/projects/${org.slug}/${project.slug}/stacktrace-link/`, - body: { - config, - sourceUrl: 'https://github.com/username/path/to/file.py', - integrations: [integration], - }, - }); - MockApiClient.addMockResponse({ - url: `/projects/${org.slug}/${project.slug}/stacktrace-coverage/`, - body: {status: CodecovStatusCode.NO_COVERAGE_DATA}, - }); - render( - , - { - organization, - } - ); - expect(await screen.findByText('Code Coverage not found')).toBeInTheDocument(); - }); - - it('skips codecov when the feature is disabled at org level', async () => { - const organization = { - ...org, - codecovAccess: false, - features: ['codecov-integration'], - }; - MockApiClient.addMockResponse({ - url: `/projects/${org.slug}/${project.slug}/stacktrace-link/`, - body: { - config, - sourceUrl: 'https://github.com/username/path/to/file.py', - integrations: [integration], - }, - }); - const stacktraceCoverageMock = MockApiClient.addMockResponse({ - url: `/projects/${org.slug}/${project.slug}/stacktrace-coverage/`, - body: {status: CodecovStatusCode.NO_COVERAGE_DATA}, - }); - render( - , - { - organization, - } - ); - expect( - await screen.findByRole('button', {name: 'Open this line in GitHub'}) - ).toBeInTheDocument(); - expect(stacktraceCoverageMock).not.toHaveBeenCalled(); - }); - it('renders the link using a valid sourceLink for a .NET project', async () => { const dotnetFrame = { filename: 'path/to/file.py', diff --git a/static/app/components/events/interfaces/frame/stacktraceLink.tsx b/static/app/components/events/interfaces/frame/stacktraceLink.tsx index b27642786aecca..05772a0e74fd5e 100644 --- a/static/app/components/events/interfaces/frame/stacktraceLink.tsx +++ b/static/app/components/events/interfaces/frame/stacktraceLink.tsx @@ -5,19 +5,12 @@ import styled from '@emotion/styled'; import {Button, LinkButton, type LinkButtonProps} from '@sentry/scraps/button'; import {Flex} from '@sentry/scraps/layout'; import {useModal} from '@sentry/scraps/modal'; -import {Text} from '@sentry/scraps/text'; import {Tooltip} from '@sentry/scraps/tooltip'; import {CopyFrameLink} from 'sentry/components/events/interfaces/frame/copyFrameLink'; -import {useStacktraceCoverage} from 'sentry/components/events/interfaces/frame/useStacktraceCoverage'; import {hasFileExtension} from 'sentry/components/events/interfaces/frame/utils'; -import {Placeholder} from 'sentry/components/placeholder'; -import {IconWarning} from 'sentry/icons'; import {t} from 'sentry/locale'; import type {Event, Frame} from 'sentry/types/event'; -import type {StacktraceLinkResult} from 'sentry/types/integrations'; -import {CodecovStatusCode} from 'sentry/types/integrations'; -import type {Organization} from 'sentry/types/organization'; import {trackAnalytics} from 'sentry/utils/analytics'; import {getAnalyticsDataForEvent} from 'sentry/utils/events'; import {getIntegrationIcon, getIntegrationSourceUrl} from 'sentry/utils/integrationUtil'; @@ -89,21 +82,6 @@ export function StacktraceLink({frame, event, line, disableSetup}: StacktraceLin enabled: isQueryEnabled, // The query will not run until `isQueryEnabled` is true } ); - const coverageEnabled = - isQueryEnabled && - organization.codecovAccess && - organization.features.includes('codecov-integration'); - const {data: coverage, isPending: isLoadingCoverage} = useStacktraceCoverage( - { - event, - frame, - orgSlug: organization.slug, - projectSlug: project?.slug, - }, - { - enabled: coverageEnabled, - } - ); useRouteAnalyticsParams( match @@ -202,17 +180,6 @@ export function StacktraceLink({frame, event, line, disableSetup}: StacktraceLin icon={getIntegrationIcon(match.config.provider.key, DEFAULT_ICON_SIZE)} /> - {coverageEnabled && isLoadingCoverage ? ( - - ) : coverage && - shouldShowCodecovFeatures(organization, match, coverage.status) ? ( - - ) : null} ); } @@ -239,17 +206,6 @@ export function StacktraceLink({frame, event, line, disableSetup}: StacktraceLin icon={getIntegrationIcon('github', DEFAULT_ICON_SIZE)} /> - {coverageEnabled && isLoadingCoverage ? ( - - ) : coverage && - shouldShowCodecovFeatures(organization, match, coverage.status) ? ( - - ) : null} ); } @@ -317,72 +273,12 @@ export function StacktraceLink({frame, event, line, disableSetup}: StacktraceLin return null; } -function shouldShowCodecovFeatures( - organization: Organization, - match: StacktraceLinkResult, - codecovStatus: CodecovStatusCode -) { - return ( - codecovStatus && - codecovStatus !== CodecovStatusCode.NO_INTEGRATION && - organization.codecovAccess && - match.config?.provider.key === 'github' - ); -} - // This should never have been set, as the icons inside buttons already auto adjust // depending on the button size, however the reason it cannot be removed is that the icon // function initializes a default argument for the icon size to md, meaning we cannot simply remove it. const DEFAULT_ICON_SIZE = 'xs'; const DEFAULT_BUTTON_SIZE = 'xs'; -interface CodecovLinkProps { - event: Event; - organization: Organization; - coverageUrl?: string; - status?: CodecovStatusCode; -} - -function CodecovLink({ - coverageUrl, - status = CodecovStatusCode.COVERAGE_EXISTS, - organization, - event, -}: CodecovLinkProps) { - if (status === CodecovStatusCode.NO_COVERAGE_DATA) { - return ( - - {t('Code Coverage not found')} - - - ); - } - - if (status !== CodecovStatusCode.COVERAGE_EXISTS || !coverageUrl) { - return null; - } - - const onOpenCodecovLink = (e: React.MouseEvent) => { - e.stopPropagation(); - trackAnalytics('integrations.stacktrace_codecov_link_clicked', { - view: 'stacktrace_issue_details', - organization, - group_id: event.groupID ? parseInt(event.groupID, 10) : -1, - ...getAnalyticsDataForEvent(event), - }); - }; - - return ( - - - - ); -} const fadeIn = keyframes` from { opacity: 0; } to { opacity: 1; } diff --git a/static/app/components/events/interfaces/frame/useStacktraceCoverage.tsx b/static/app/components/events/interfaces/frame/useStacktraceCoverage.tsx deleted file mode 100644 index cf7c2261fc41f3..00000000000000 --- a/static/app/components/events/interfaces/frame/useStacktraceCoverage.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import {buildStacktraceLinkQuery} from 'sentry/components/events/interfaces/frame/useStacktraceLink'; -import type {Event, Frame} from 'sentry/types/event'; -import type {CodecovResponse} from 'sentry/types/integrations'; -import {getApiUrl} from 'sentry/utils/api/getApiUrl'; -import type {ApiQueryKey, UseApiQueryOptions} from 'sentry/utils/queryClient'; -import {useApiQuery} from 'sentry/utils/queryClient'; - -interface UseStacktraceCoverageProps { - event: Partial>; - frame: Partial< - Pick - >; - orgSlug: string; - projectSlug: string | undefined; -} - -const stacktraceCoverageQueryKey = ( - orgSlug: string, - projectSlug: string | undefined, - query: ReturnType -): ApiQueryKey => [ - getApiUrl('/projects/$organizationIdOrSlug/$projectIdOrSlug/stacktrace-coverage/', { - path: { - organizationIdOrSlug: orgSlug, - projectIdOrSlug: projectSlug!, - }, - }), - {query}, -]; - -export function useStacktraceCoverage( - {event, frame, orgSlug, projectSlug}: UseStacktraceCoverageProps, - options: Partial> = {} -) { - const query = buildStacktraceLinkQuery(event, frame); - return useApiQuery( - stacktraceCoverageQueryKey(orgSlug, projectSlug, query), - { - staleTime: Infinity, - retry: false, - ...options, - } - ); -} diff --git a/static/app/components/stackTrace/frame/frameContent.tsx b/static/app/components/stackTrace/frame/frameContent.tsx index bac23ded5d2764..693d12670891f8 100644 --- a/static/app/components/stackTrace/frame/frameContent.tsx +++ b/static/app/components/stackTrace/frame/frameContent.tsx @@ -1,10 +1,8 @@ import {Activity, useRef} from 'react'; -import {css} from '@emotion/react'; import styled from '@emotion/styled'; import {Container} from '@sentry/scraps/layout'; import {Text} from '@sentry/scraps/text'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {Assembly} from 'sentry/components/events/interfaces/frame/assembly'; import {FrameRegisters} from 'sentry/components/events/interfaces/frame/frameRegisters'; @@ -21,24 +19,14 @@ import { useStackTraceFrameContext, } from 'sentry/components/stackTrace/stackTraceContext'; import {t} from 'sentry/locale'; -import {Coverage} from 'sentry/types/integrations'; import {getFileExtension} from 'sentry/utils/fileExtension'; -const COVERAGE_TEXT: Record = { - [Coverage.NOT_COVERED]: t('Line uncovered by tests'), - [Coverage.COVERED]: t('Line covered by tests'), - [Coverage.PARTIAL]: t('Line partially covered by tests'), - [Coverage.NOT_APPLICABLE]: undefined, -}; - interface FrameContentProps { effectiveContext?: Array<[number, string | null]>; isLoadingSourceContext?: boolean; - sourceLineCoverage?: Array; } export function FrameContent({ - sourceLineCoverage = [], effectiveContext, isLoadingSourceContext, }: FrameContentProps) { @@ -101,22 +89,12 @@ export function FrameContent({ key={`${lineNumber}-${lineIndex}`} isActive={lineNumber === frame.lineNo} > - - - {lineNumber} - - + {lineNumber} + @@ -183,7 +161,6 @@ const FrameSourceRow = styled('div')<{isActive: boolean}>` `; const FrameSourceLineNumber = styled('div')<{ - coverage: Coverage; isActive: boolean; }>` display: flex; @@ -198,49 +175,6 @@ const FrameSourceLineNumber = styled('div')<{ user-select: none; padding-inline: 1ch; border-right: 3px solid transparent; - - ${p => - p.coverage === Coverage.COVERED && - css` - background: ${p.theme.colors.green100}; - border-right-color: ${p.theme.tokens.border.success.vibrant}; - `} - - ${p => - p.coverage === Coverage.NOT_COVERED && - css` - background: ${p.theme.colors.red100}; - border-right-color: ${p.theme.tokens.border.danger.vibrant}; - `} - - ${p => - p.coverage === Coverage.PARTIAL && - css` - background: ${p.theme.colors.yellow100}; - border-right-style: dashed; - border-right-color: ${p.theme.tokens.border.warning.vibrant}; - `} - - ${p => - p.isActive && - p.coverage === Coverage.PARTIAL && - css` - background: ${p.theme.colors.yellow200}; - `} - - ${p => - p.isActive && - p.coverage === Coverage.COVERED && - css` - background: ${p.theme.colors.green200}; - `} - - ${p => - p.isActive && - p.coverage === Coverage.NOT_COVERED && - css` - background: ${p.theme.colors.red200}; - `} `; // overrides code[class*='language-'] in global.tsx diff --git a/static/app/components/stackTrace/issueStackTrace/index.spec.tsx b/static/app/components/stackTrace/issueStackTrace/index.spec.tsx index 30f98ee29d75a5..9c7bde64f8aafa 100644 --- a/static/app/components/stackTrace/issueStackTrace/index.spec.tsx +++ b/static/app/components/stackTrace/issueStackTrace/index.spec.tsx @@ -8,7 +8,6 @@ import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrar import {IssueStackTrace} from 'sentry/components/stackTrace/issueStackTrace'; import {ProjectsStore} from 'sentry/stores/projectsStore'; -import {CodecovStatusCode, Coverage} from 'sentry/types/integrations'; import type {StacktraceType} from 'sentry/types/stacktrace'; type StacktraceWithFrames = StacktraceType & { @@ -297,59 +296,6 @@ describe('IssueStackTrace', () => { expect(reorderedHeadings[2]).toHaveTextContent('LeafError'); }); - it('renders coverage tooltip from issue-level coverage request', async () => { - const {event, stacktrace} = makeStackTraceData(); - const organization = OrganizationFixture({ - slug: 'org-slug', - codecovAccess: true, - }); - const project = ProjectFixture({ - id: event.projectID, - slug: 'project-slug', - }); - ProjectsStore.loadInitialData([project]); - const coverageRequest = MockApiClient.addMockResponse({ - url: `/projects/${organization.slug}/${project.slug}/stacktrace-coverage/`, - body: { - status: CodecovStatusCode.COVERAGE_EXISTS, - lineCoverage: [ - [110, Coverage.COVERED], - [111, Coverage.PARTIAL], - [112, Coverage.NOT_COVERED], - ], - }, - }); - - render( - , - {organization} - ); - - expect( - await screen.findByTestId('core-stacktrace-frame-context') - ).toBeInTheDocument(); - expect(coverageRequest).toHaveBeenCalled(); - - await userEvent.hover(screen.getByLabelText('Line 112')); - - await waitFor(() => - expect(screen.getAllByText('Line uncovered by tests')).toHaveLength(1) - ); - }); - it('renders annotated text when exception value has PII scrubbing metadata', async () => { const {stacktrace} = makeStackTraceData(); const entryIndex = 0; diff --git a/static/app/components/stackTrace/issueStackTrace/issueStackTraceFrameContext.tsx b/static/app/components/stackTrace/issueStackTrace/issueStackTraceFrameContext.tsx index 07903ad9d31dbd..b3c6daf068afd0 100644 --- a/static/app/components/stackTrace/issueStackTrace/issueStackTraceFrameContext.tsx +++ b/static/app/components/stackTrace/issueStackTrace/issueStackTraceFrameContext.tsx @@ -1,7 +1,6 @@ import {useMemo} from 'react'; import {useSourceContext} from 'sentry/components/events/interfaces/frame/useSourceContext'; -import {useStacktraceCoverage} from 'sentry/components/events/interfaces/frame/useStacktraceCoverage'; import { hasContextSource, hasPotentialSourceContext, @@ -11,22 +10,9 @@ import { useStackTraceContext, useStackTraceFrameContext, } from 'sentry/components/stackTrace/stackTraceContext'; -import { - CodecovStatusCode, - type Coverage, - type LineCoverage, -} from 'sentry/types/integrations'; import {defined} from 'sentry/utils'; import {useOrganization} from 'sentry/utils/useOrganization'; -function getLineCoverage( - lines: Array<[number, string | null]>, - lineCoverage: LineCoverage[] -): Array { - const coverageByLine = new Map(lineCoverage); - return lines.map(([lineNo]) => coverageByLine.get(lineNo)); -} - export function IssueStackTraceFrameContext() { const {event, frame, isExpanded} = useStackTraceFrameContext(); const {hasScmSourceContext, project} = useStackTraceContext(); @@ -58,30 +44,9 @@ export function IssueStackTraceFrameContext() { }, [sourceContextData]); const effectiveContext = hasEmbeddedContext ? frame.context : scmContext; - const contextLines = isExpanded ? (effectiveContext ?? []) : []; - - const {data: coverageData, isPending: isLoadingCoverage} = useStacktraceCoverage( - { - event, - frame, - orgSlug: organization.slug, - projectSlug: project?.slug, - }, - { - enabled: isExpanded && defined(project) && !!organization.codecovAccess, - } - ); - - const sourceLineCoverage = - !isLoadingCoverage && - coverageData?.status === CodecovStatusCode.COVERAGE_EXISTS && - coverageData.lineCoverage - ? getLineCoverage(contextLines, coverageData.lineCoverage) - : []; return ( diff --git a/static/app/components/stackTrace/issueStackTrace/sharedIssueStackTrace.tsx b/static/app/components/stackTrace/issueStackTrace/sharedIssueStackTrace.tsx index 3be882d07e88c2..a86f40bdae152e 100644 --- a/static/app/components/stackTrace/issueStackTrace/sharedIssueStackTrace.tsx +++ b/static/app/components/stackTrace/issueStackTrace/sharedIssueStackTrace.tsx @@ -67,7 +67,7 @@ type SharedIssueStackTraceProps = * The shared issue page is viewed by unauthenticated users, so this component * intentionally avoids the following from {@link IssueStackTrace}: * - {@link IssueFrameActions}: calls stacktrace-link and source-map-debug APIs - * - {@link IssueStackTraceFrameContext}: calls stacktrace-coverage API (Codecov) + * - {@link IssueStackTraceFrameContext}: fetches SCM source context when expanded (authenticated) * - {@link StacktraceBanners}: depends on authenticated project context * - {@link SuspectCommits}: requires group and project data * diff --git a/static/app/components/stackTrace/stackTrace.stories.tsx b/static/app/components/stackTrace/stackTrace.stories.tsx index ef6396f6c3b7f6..5976206ee70454 100644 --- a/static/app/components/stackTrace/stackTrace.stories.tsx +++ b/static/app/components/stackTrace/stackTrace.stories.tsx @@ -32,7 +32,6 @@ import { type ExceptionValue, type Frame, } from 'sentry/types/event'; -import {Coverage} from 'sentry/types/integrations'; import type {StacktraceType} from 'sentry/types/stacktrace'; type StacktraceWithFrames = StacktraceType & { @@ -44,18 +43,6 @@ type StackTraceStoryData = { stacktrace: StacktraceWithFrames; }; -function getSampleSourceLineCoverage(length: number): Coverage[] { - return Array.from({length}, (_, index) => { - if (index % 3 === 0) { - return Coverage.COVERED; - } - if (index % 3 === 1) { - return Coverage.NOT_COVERED; - } - return Coverage.PARTIAL; - }); -} - function makeEvent(overrides: Partial = {}): Event { return { id: '1', @@ -1057,7 +1044,7 @@ export default Storybook.story('StackTrace', story => { ); }); - story('StackTraceFrames - Single Frame Source Coverage', () => { + story('StackTraceFrames - Single frame with embedded source context', () => { const {event, stacktrace} = makeStackTraceData(); const context: Frame['context'] = [ @@ -1069,22 +1056,17 @@ export default Storybook.story('StackTrace', story => { [6, ' raise ValueError("bad data")'], [7, ' return result'], ]; - const sourceLineCoverage = getSampleSourceLineCoverage(context.length); const singleFrameStacktrace = { ...stacktrace, frames: [makeFrame({context, lineNo: 6, inApp: true})], }; - function CoveredFrameContext() { - return ; - } - return ( diff --git a/static/app/types/integrations.tsx b/static/app/types/integrations.tsx index 1f826503409be4..375a41f1b67014 100644 --- a/static/app/types/integrations.tsx +++ b/static/app/types/integrations.tsx @@ -205,27 +205,6 @@ type SentryAppSchemaAlertRuleActionSettings = { optional_fields?: any[]; }; -export enum Coverage { - NOT_APPLICABLE = -1, - COVERED = 0, - NOT_COVERED = 1, - PARTIAL = 2, -} -export type LineCoverage = [lineNo: number, coverage: Coverage]; - -export enum CodecovStatusCode { - COVERAGE_EXISTS = 200, - NO_INTEGRATION = 404, - NO_COVERAGE_DATA = 400, -} - -export interface CodecovResponse { - status: CodecovStatusCode; - attemptedUrl?: string; - coverageUrl?: string; - lineCoverage?: LineCoverage[]; -} - export interface StacktraceLinkResult { integrations: Integration[]; attemptedUrl?: string;