diff --git a/static/app/views/alerts/rules/uptime/httpSnippet.spec.tsx b/static/app/views/alerts/rules/uptime/httpSnippet.spec.tsx index 8adc5980055bf1..7df1d079e87259 100644 --- a/static/app/views/alerts/rules/uptime/httpSnippet.spec.tsx +++ b/static/app/views/alerts/rules/uptime/httpSnippet.spec.tsx @@ -1,3 +1,5 @@ +import {generateSentryTraceHeader} from '@sentry/utils'; + import {render} from 'sentry-test/reactTestingLibrary'; import {HTTPSnippet} from './httpSnippet'; @@ -15,9 +17,16 @@ describe('HTTPSnippet', function () { method="POST" body={'{"key": "value"}'} headers={[['X-Something', 'Header Value']]} + traceSampling={false} /> ); + expect(jest.mocked(generateSentryTraceHeader)).toHaveBeenCalledWith( + undefined, + undefined, + false + ); + const expected = [ 'POST /test?query=value HTTP/1.1', 'Host: example.com', diff --git a/static/app/views/alerts/rules/uptime/httpSnippet.tsx b/static/app/views/alerts/rules/uptime/httpSnippet.tsx index fcfbdcca37dece..4eb4870d19ddaf 100644 --- a/static/app/views/alerts/rules/uptime/httpSnippet.tsx +++ b/static/app/views/alerts/rules/uptime/httpSnippet.tsx @@ -1,4 +1,4 @@ -import {useState} from 'react'; +import {useMemo} from 'react'; import styled from '@emotion/styled'; import {generateSentryTraceHeader} from '@sentry/utils'; @@ -10,12 +10,15 @@ interface Props { body: string | null; headers: Array<[key: string, value: string]>; method: string; + traceSampling: boolean; url: string; } -export function HTTPSnippet({body, headers, method, url}: Props) { - const [exampleTrace] = useState(() => - generateSentryTraceHeader(undefined, undefined, true) +export function HTTPSnippet({body, headers, method, url, traceSampling}: Props) { + const exampleTrace = useMemo( + () => + generateSentryTraceHeader(undefined, undefined, traceSampling ? undefined : false), + [traceSampling] ); const urlObject = safeURL(url); diff --git a/static/app/views/alerts/rules/uptime/types.tsx b/static/app/views/alerts/rules/uptime/types.tsx index 79eb43a862f83d..5aab4d2ad8c4e0 100644 --- a/static/app/views/alerts/rules/uptime/types.tsx +++ b/static/app/views/alerts/rules/uptime/types.tsx @@ -24,5 +24,6 @@ export interface UptimeRule { projectSlug: string; status: UptimeMonitorStatus; timeoutMs: number; + traceSampling: boolean; url: string; } diff --git a/static/app/views/alerts/rules/uptime/uptimeAlertForm.spec.tsx b/static/app/views/alerts/rules/uptime/uptimeAlertForm.spec.tsx index cecf25cf40ad11..8f6f8e42c9f45b 100644 --- a/static/app/views/alerts/rules/uptime/uptimeAlertForm.spec.tsx +++ b/static/app/views/alerts/rules/uptime/uptimeAlertForm.spec.tsx @@ -54,6 +54,8 @@ describe('Uptime Alert Form', function () { await userEvent.type(input('Name of header 1'), 'X-Something'); await userEvent.type(input('Value of X-Something'), 'Header Value'); + await userEvent.click(screen.getByRole('checkbox', {name: 'Allow Tracing'})); + const name = input('Uptime rule name'); await userEvent.clear(name); await userEvent.type(name, 'New Uptime Rule'); @@ -78,6 +80,7 @@ describe('Uptime Alert Form', function () { method: 'POST', headers: [['X-Something', 'Header Value']], body: '{"key": "value"}', + traceSampling: true, intervalSeconds: 60, }), }) @@ -96,6 +99,7 @@ describe('Uptime Alert Form', function () { ['X-Test2', 'value 2'], ], body: '{"key": "value"}', + traceSampling: true, owner: ActorFixture(), }); render( @@ -115,6 +119,7 @@ describe('Uptime Alert Form', function () { expect(screen.getByRole('menuitemradio', {name: 'POST'})).toBeChecked(); await selectEvent.openMenu(input('Environment')); expect(screen.getByRole('menuitemradio', {name: 'prod'})).toBeChecked(); + expect(screen.getByRole('checkbox', {name: 'Allow Tracing'})).toBeChecked(); }); it('handles simple edits', async function () { @@ -163,6 +168,7 @@ describe('Uptime Alert Form', function () { projectSlug: project.slug, url: 'https://existing-url.com', owner: ActorFixture(), + traceSampling: false, }); render( , @@ -188,6 +194,8 @@ describe('Uptime Alert Form', function () { await userEvent.type(input('Name of header 2'), 'X-Another'); await userEvent.type(input('Value of X-Another'), 'Second Value'); + await userEvent.click(screen.getByRole('checkbox', {name: 'Allow Tracing'})); + const name = input('Uptime rule name'); await userEvent.clear(name); await userEvent.type(name, 'Updated name'); @@ -216,6 +224,7 @@ describe('Uptime Alert Form', function () { ], body: '{"different": "value"}', intervalSeconds: 60 * 10, + traceSampling: true, }), }) ); diff --git a/static/app/views/alerts/rules/uptime/uptimeAlertForm.tsx b/static/app/views/alerts/rules/uptime/uptimeAlertForm.tsx index a9d81852551288..13f0daf779e7ab 100644 --- a/static/app/views/alerts/rules/uptime/uptimeAlertForm.tsx +++ b/static/app/views/alerts/rules/uptime/uptimeAlertForm.tsx @@ -6,6 +6,7 @@ import {Observer} from 'mobx-react'; import {Button} from 'sentry/components/button'; import Confirm from 'sentry/components/confirm'; import FieldWrapper from 'sentry/components/forms/fieldGroup/fieldWrapper'; +import BooleanField from 'sentry/components/forms/fields/booleanField'; import HiddenField from 'sentry/components/forms/fields/hiddenField'; import SelectField from 'sentry/components/forms/fields/selectField'; import SentryMemberTeamSelectorField from 'sentry/components/forms/fields/sentryMemberTeamSelectorField'; @@ -62,6 +63,7 @@ function getFormDataFromRule(rule: UptimeRule) { body: rule.body, headers: rule.headers, intervalSeconds: rule.intervalSeconds, + traceSampling: rule.traceSampling, owner: rule.owner ? `${rule.owner.type}:${rule.owner.id}` : null, }; } @@ -216,6 +218,15 @@ export function UptimeAlertForm({project, handleDelete, rule}: Props) { label={t('Headers')} flexibleControlStateSize /> + )} diff --git a/tests/js/fixtures/uptimeRule.ts b/tests/js/fixtures/uptimeRule.ts index a3d5d2a123779d..1c232e27648822 100644 --- a/tests/js/fixtures/uptimeRule.ts +++ b/tests/js/fixtures/uptimeRule.ts @@ -16,6 +16,7 @@ export function UptimeRuleFixture(params: Partial = {}): UptimeRule headers: [], method: 'GET', body: null, + traceSampling: false, ...params, } }