Skip to content

Commit 993d057

Browse files
authored
Merge branch 'master' into jcallender/aci/organize-defaults-code
2 parents 2f3a48c + 65bd267 commit 993d057

File tree

13 files changed

+436
-71
lines changed

13 files changed

+436
-71
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
610610
/static/app/gettingStartedDocs/ @getsentry/value-discovery
611611
/static/app/types/project.tsx @getsentry/value-discovery
612612
/static/app/views/onboarding/ @getsentry/value-discovery
613+
/tests/acceptance/test_scm_onboarding.py @getsentry/value-discovery
613614
/tests/js/fixtures/detectedPlatform.ts @getsentry/value-discovery
614615
/static/app/views/projectInstall/ @getsentry/value-discovery
615616
/src/sentry/onboarding_tasks/ @getsentry/value-discovery

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
"echarts-for-react": "3.0.6",
172172
"esbuild": "0.25.10",
173173
"focus-trap": "7.6.5",
174-
"framer-motion": "12.23.12",
174+
"framer-motion": "12.38.0",
175175
"fuse.js": "^6.6.2",
176176
"gettext-parser": "7.0.1",
177177
"gl-matrix": "3.4.4",

pnpm-lock.yaml

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/sentry/api/serializers/models/organization.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -920,8 +920,3 @@ def serialize( # type: ignore[override]
920920
)
921921

922922
return context
923-
924-
925-
# Backwards-compatible aliases for getsentry
926-
DetailedOrganizationSerializer = OrganizationSerializer
927-
DetailedOrganizationSerializerWithProjectsAndTeams = OrganizationWithProjectsAndTeamsSerializer

src/sentry/features/temporary.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ def register_temporary_features(manager: FeatureManager) -> None:
141141
manager.add("organizations:integrations-perforce", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
142142
manager.add("organizations:integrations-slack-staging", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
143143
manager.add("organizations:scm-source-context", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
144+
# API-driven integration setup pipeline (per-provider rollout)
145+
manager.add("organizations:integration-api-pipeline-github", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
144146
# Project Management Integrations Feature Parity Flags
145147
manager.add("organizations:integrations-github_enterprise-project-management", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
146148
manager.add("organizations:integrations-gitlab-project-management", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)

src/sentry/grouping/parameterization.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ class ParameterizationRegex:
1818
name: str # name of the pattern (also used as group name in combined regex)
1919
raw_pattern: str # regex pattern w/o matching group name
2020
raw_pattern_experimental: str | None = None
21-
lookbehind: str | None = None # positive lookbehind prefix if needed
22-
lookahead: str | None = None # positive lookahead postfix if needed
2321
# Function which takes the matched value and returns the replacement value.
2422
replacement_callback: ParameterizationReplacementFunction | None = None
2523

@@ -38,11 +36,9 @@ def experimental_pattern(self) -> str | None:
3836

3937
def _get_pattern(self, raw_pattern: str) -> str:
4038
"""
41-
Returns the regex pattern with a named matching group and lookbehind/lookahead if needed.
39+
Returns the regex pattern inside of a named matching group.
4240
"""
43-
prefix = rf"(?<={self.lookbehind})" if self.lookbehind else ""
44-
postfix = rf"(?={self.lookahead})" if self.lookahead else ""
45-
return rf"{prefix}(?P<{self.name}>{raw_pattern}){postfix}"
41+
return rf"(?P<{self.name}>{raw_pattern})"
4642

4743

4844
def is_valid_ip(maybe_ip_str: str) -> bool:
@@ -311,23 +307,25 @@ def is_valid_ip(maybe_ip_str: str) -> bool:
311307
ParameterizationRegex(
312308
name="quoted_str",
313309
raw_pattern=r"""
314-
'([^']+)' | "([^"]+)"
310+
# Lookbehind to ensure we'll only match the value half of `<key>=<value>`-type key-value
311+
# pairs, rather than all quoted strings
312+
(?<=[=])
313+
(
314+
'([^']+)' |
315+
"([^"]+)"
316+
)
315317
""",
316-
# Using an `=` lookbehind guarantees we'll only match the value half of key-value pairs,
317-
# rather than all quoted strings
318-
lookbehind="=",
319318
),
320319
ParameterizationRegex(
321320
name="bool",
322321
raw_pattern=r"""
323-
True |
324-
true |
325-
False |
326-
false
322+
# Lookbehind to ensure we'll only match the value half of `<key>=<value>`-type key-value
323+
# pairs, rather than all instances of the words 'true' and 'false'
324+
(?<=[=])
325+
(
326+
True | true | False | false
327+
)
327328
""",
328-
# Using an `=` lookbehind guarantees we'll only match the value half of key-value pairs,
329-
# rather than all instances of the words 'true' and 'false'.
330-
lookbehind="=",
331329
),
332330
]
333331

static/app/views/issueList/actions/index.spec.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,24 +108,24 @@ describe('IssueListActions', () => {
108108
expect(screen.queryByRole('button', {name: 'Archive'})).not.toBeInTheDocument();
109109
});
110110

111-
it('shows action buttons when any items are selected', () => {
111+
it('shows action buttons when any items are selected', async () => {
112112
render(<WrappedComponent selectedIds={['1']} />);
113113

114-
expect(screen.getByRole('button', {name: 'Resolve'})).toBeEnabled();
114+
expect(await screen.findByRole('button', {name: 'Resolve'})).toBeEnabled();
115115
expect(screen.getByRole('button', {name: 'Archive'})).toBeEnabled();
116116
});
117117

118-
it('shows select all checkbox as checked when all items are selected', () => {
118+
it('shows select all checkbox as checked when all items are selected', async () => {
119119
render(<WrappedComponent selectedIds={['1', '2', '3']} />);
120120

121121
// When all selected, label changes to "Deselect all"
122-
expect(screen.getByRole('checkbox', {name: 'Deselect all'})).toBeChecked();
122+
expect(await screen.findByRole('checkbox', {name: 'Deselect all'})).toBeChecked();
123123
});
124124

125-
it('shows select all checkbox as indeterminate when some items are selected', () => {
125+
it('shows select all checkbox as indeterminate when some items are selected', async () => {
126126
render(<WrappedComponent selectedIds={['1']} />);
127127

128-
const checkbox = screen.getByRole('checkbox', {name: 'Select all'});
128+
const checkbox = await screen.findByRole('checkbox', {name: 'Select all'});
129129
expect(checkbox).toBePartiallyChecked();
130130
});
131131
});

static/app/views/navigation/index.desktop.spec.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -851,9 +851,8 @@ describe('desktop navigation', () => {
851851

852852
await userEvent.hover(screen.getByRole('link', {name: 'Explore'}));
853853

854-
expect(
855-
await within(secondaryNav).findByRole('link', {name: 'Traces'})
856-
).toBeInTheDocument();
854+
// Re-query secondary nav because AnimatePresence remounts it with a new key
855+
expect(await screen.findByRole('link', {name: 'Traces'})).toBeInTheDocument();
857856
});
858857

859858
it('shows hovered group content in the peek view when sidebar is collapsed', async () => {

static/app/views/seerExplorer/explorerPanel.spec.tsx

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,15 @@ describe('ExplorerPanel', () => {
125125
});
126126

127127
describe('Feature Flag and Organization Checks', () => {
128-
it('renders when feature flag and open membership are enabled', () => {
128+
it('renders when feature flag and open membership are enabled', async () => {
129129
renderWithPanelContext(<ExplorerPanel />, true, {organization});
130130

131131
expect(
132-
screen.getByText(/Ask Seer anything about your application./)
132+
await screen.findByText(/Ask Seer anything about your application./)
133133
).toBeInTheDocument();
134134
});
135135

136-
it('does not render when feature flag is disabled', () => {
136+
it('does not render when feature flag is disabled', async () => {
137137
const disabledOrg = OrganizationFixture({
138138
features: [],
139139
hideAiFeatures: false,
@@ -144,10 +144,10 @@ describe('ExplorerPanel', () => {
144144
organization: disabledOrg,
145145
});
146146

147-
expect(container).toBeEmptyDOMElement();
147+
await waitFor(() => expect(container).toBeEmptyDOMElement());
148148
});
149149

150-
it('does not render when AI features are hidden', () => {
150+
it('does not render when AI features are hidden', async () => {
151151
const disabledOrg = OrganizationFixture({
152152
features: ['seer-explorer'],
153153
hideAiFeatures: true,
@@ -158,10 +158,10 @@ describe('ExplorerPanel', () => {
158158
organization: disabledOrg,
159159
});
160160

161-
expect(container).toBeEmptyDOMElement();
161+
await waitFor(() => expect(container).toBeEmptyDOMElement());
162162
});
163163

164-
it('does not render when open membership is disabled', () => {
164+
it('does not render when open membership is disabled', async () => {
165165
const disabledOrg = OrganizationFixture({
166166
features: ['seer-explorer'],
167167
hideAiFeatures: false,
@@ -172,28 +172,30 @@ describe('ExplorerPanel', () => {
172172
organization: disabledOrg,
173173
});
174174

175-
expect(container).toBeEmptyDOMElement();
175+
await waitFor(() => expect(container).toBeEmptyDOMElement());
176176
});
177177
});
178178

179179
describe('Empty State', () => {
180-
it('shows empty state when no messages exist', () => {
180+
it('shows empty state when no messages exist', async () => {
181181
renderWithPanelContext(<ExplorerPanel />, true, {organization});
182182

183183
expect(
184-
screen.getByText(/Ask Seer anything about your application./)
184+
await screen.findByText(/Ask Seer anything about your application./)
185185
).toBeInTheDocument();
186186
});
187187

188-
it('shows input section in empty state', () => {
188+
it('shows input section in empty state', async () => {
189189
renderWithPanelContext(<ExplorerPanel />, true, {organization});
190190

191191
expect(
192-
screen.getByPlaceholderText('Type your message or / command and press Enter ↵')
192+
await screen.findByPlaceholderText(
193+
'Type your message or / command and press Enter ↵'
194+
)
193195
).toBeInTheDocument();
194196
});
195197

196-
it('shows error when hook returns isError=true', () => {
198+
it('shows error when hook returns isError=true', async () => {
197199
const useSeerExplorerSpy = jest
198200
.spyOn(useSeerExplorerModule, 'useSeerExplorer')
199201
.mockReturnValue({
@@ -220,7 +222,7 @@ describe('ExplorerPanel', () => {
220222
renderWithPanelContext(<ExplorerPanel />, true, {organization});
221223

222224
expect(
223-
screen.getByText('Error loading this session (ID=123).')
225+
await screen.findByText('Error loading this session (ID=123).')
224226
).toBeInTheDocument();
225227
expect(
226228
screen.queryByText(/Ask Seer anything about your application./)
@@ -231,7 +233,7 @@ describe('ExplorerPanel', () => {
231233
});
232234

233235
describe('Messages Display', () => {
234-
it('renders messages when session data exists', () => {
236+
it('renders messages when session data exists', async () => {
235237
const mockSessionData = {
236238
blocks: [
237239
{
@@ -283,7 +285,7 @@ describe('ExplorerPanel', () => {
283285

284286
renderWithPanelContext(<ExplorerPanel />, true, {organization});
285287

286-
expect(screen.getByText('What is this error?')).toBeInTheDocument();
288+
expect(await screen.findByText('What is this error?')).toBeInTheDocument();
287289
expect(
288290
screen.getByText('This error indicates a null pointer exception.')
289291
).toBeInTheDocument();
@@ -533,19 +535,21 @@ describe('ExplorerPanel', () => {
533535
openMembership: true,
534536
});
535537

536-
it('does not render the toggle when the feature flag is disabled', () => {
538+
it('does not render the toggle when the feature flag is disabled', async () => {
537539
renderWithPanelContext(<ExplorerPanel />, true, {organization});
538540

541+
// Wait for effects to settle before asserting absence
542+
await screen.findByTestId('seer-explorer-input');
539543
expect(
540544
screen.queryByRole('checkbox', {name: 'Toggle context engine'})
541545
).not.toBeInTheDocument();
542546
});
543547

544-
it('renders the toggle when the feature flag is enabled', () => {
548+
it('renders the toggle when the feature flag is enabled', async () => {
545549
renderWithPanelContext(<ExplorerPanel />, true, {organization: orgWithFlag});
546550

547551
expect(
548-
screen.getByRole('checkbox', {name: 'Toggle context engine'})
552+
await screen.findByRole('checkbox', {name: 'Toggle context engine'})
549553
).toBeInTheDocument();
550554
});
551555

@@ -623,20 +627,20 @@ describe('ExplorerPanel', () => {
623627
});
624628

625629
describe('Visibility Control', () => {
626-
it('renders when isVisible=true', () => {
630+
it('renders when isVisible=true', async () => {
627631
renderWithPanelContext(<ExplorerPanel />, true, {organization});
628632

629-
expect(screen.getByTestId('seer-explorer-input')).toBeInTheDocument();
633+
expect(await screen.findByTestId('seer-explorer-input')).toBeInTheDocument();
630634
});
631635

632-
it('can handle visibility changes', () => {
636+
it('can handle visibility changes', async () => {
633637
const {rerenderWithOpen} = renderWithPanelContext(<ExplorerPanel />, false, {
634638
organization,
635639
});
636640

637641
rerenderWithOpen(true);
638642

639-
expect(screen.getByTestId('seer-explorer-input')).toBeInTheDocument();
643+
expect(await screen.findByTestId('seer-explorer-input')).toBeInTheDocument();
640644
});
641645
});
642646
});

static/gsApp/utils/dataCategory.spec.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,9 +416,10 @@ describe('listDisplayNames', () => {
416416
});
417417

418418
describe('isByteCategory', () => {
419-
it('verifies isByteCategory function handles both ATTACHMENTS and LOG_BYTE', () => {
419+
it('verifies isByteCategory function handles ATTACHMENTS, LOG_BYTE, and TRACE_METRIC_BYTE', () => {
420420
expect(isByteCategory(DataCategory.ATTACHMENTS)).toBe(true);
421421
expect(isByteCategory(DataCategory.LOG_BYTE)).toBe(true);
422+
expect(isByteCategory(DataCategory.TRACE_METRIC_BYTE)).toBe(true);
422423
expect(isByteCategory(DataCategory.ERRORS)).toBe(false);
423424
expect(isByteCategory(DataCategory.TRANSACTIONS)).toBe(false);
424425
});

0 commit comments

Comments
 (0)